es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Problema al seleccionar una única celda para cada sección.

Estoy tratando de seleccionar una única celda para cada sección. Todo funciona correctamente, pero cuando desplazo la tabla hacia arriba o hacia abajo, el accesorio de marca de verificación aparece en celdas aleatorias. Aquí está el código:

tableView.allowsMultipleSelection = true

    func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
          // Encontrar cualquier fila seleccionada en esta sección
          if let selectedIndexPath = tableView.indexPathsForSelectedRows?.first(where: { $0.section == indexPath.section}) {
              // Deseleccionar la fila
              tableView.deselectRow(at: selectedIndexPath, animated: false)
              // deselectRow no dispara el método delegado, por lo que es necesario
              // quitar la marca de verificación aquí
              tableView.cellForRow(at: selectedIndexPath)?.accessoryType = .none
          }
          return indexPath
      }

       func tableView(_ tableView: UITableView, willDeselectRowAt indexPath: IndexPath) -> IndexPath? {
          // Evitar la deselección de una celda
          return nil
      }

       func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
          tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
      }

Agradecería cualquier ayuda para evitar esto.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    El problema que estás enfrentando se debe a que las celdas se reutilizan al desplazarse por la tabla. Para solucionarlo, debes restablecer el accesorio de marcas de verificación para las celdas que se están reutilizando y asegurarte de que solo se pueda seleccionar una celda por sección.

    Aquí tienes una solución posible:

    tableView.allowsMultipleSelection = true
    
    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        // Restablecer el accesorio de marcas de verificación para las celdas que se están reutilizando
        if let selectedIndexPaths = tableView.indexPathsForSelectedRows,
           selectedIndexPaths.contains(where: { $0 == indexPath }) {
            cell.accessoryType = .checkmark
        } else {
            cell.accessoryType = .none
        }
    }
    
    func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
        // Encontrar cualquier fila seleccionada en esta sección
        if let selectedIndexPath = tableView.indexPathsForSelectedRows?.first(where: { $0.section == indexPath.section }) {
            // Deseleccionar la fila
            tableView.deselectRow(at: selectedIndexPath, animated: false)
            // Desmarcar la fila seleccionada
            tableView.cellForRow(at: selectedIndexPath)?.accessoryType = .none
        }
        return indexPath
    }
    
    func tableView(_ tableView: UITableView, willDeselectRowAt indexPath: IndexPath) -> IndexPath? {
        // Evitar la deselección de una celda
        return nil
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        // Marcar con una marca de verificación la fila seleccionada
        tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
    }
    

    En esta solución, restablecemos el accesorio de la marca de verificación cuando una celda se está reutilizando utilizando el método de delegado willDisplay. También actualizamos el método de delegado willSelect para manejar adecuadamente la reutilización.

    Con estos cambios, deberías poder seleccionar una única celda por sección sin experimentar marcas de verificación aleatorias al desplazarte por la tabla.

Comments are closed.