He creado un UITableView con múltiples secciones que consisten en dos celdas con altura de celda dinámica. Se agregó un botón en la segunda celda. Al hacer clic en el botón, aumenta la altura de la segunda celda cambiando la altura de restricción. El método de acción conectado al botón es:

func increaseHeightOnClickOfButton(sender: UIButton) {
    let indexPath = IndexPath(item: 1, section: sender.tag)

    let cell = myTableView.cellForRow(at: indexPath) as! customCell
    cell.viewHeightConstraint.constant = 100

    self.myTableView.reloadRows(at: [indexPath], with: .automatic)
}

Problema : al hacer clic en el botón, la altura de la celda de la segunda sección aumenta en lugar de la primera.

También he intentado dar un valor fijo de una sección como esta:

let indexPath = IndexPath(item: 1, section: 0)

Pero no está funcionando.

Solo funciona cuando pruebo este código:

func increaseHeightOnClickOfButton(sender: UIButton) {
    let indexPath = IndexPath(item: 1, section: sender.tag)

    let cell = myTableView.cellForRow(at: indexPath) as! customCell
    cell.viewHeightConstraint.constant = 100

    self.myTableView.reloadData()
}

Pero no quiero volver a cargar toda la vista de la tabla. ¿Alguien puede ayudarme en lo que estoy haciendo mal o hay algún otro enfoque para lograrlo?

Editar :

Hice un cambio más, eliminé:

self.myTableView.reloadRows(at: [indexPath], with: .automatic)

Después de hacer clic en el botón cuando empiezo a desplazar la vista de tabla, volver a la misma celda aumenta su altura. Así que supongo que hay algún problema con reloadRows.

1
Amit 21 oct. 2017 a las 13:00

3 respuestas

La mejor respuesta

Editar:

Primera publicación modificada para incluir un DataSource para rastrear la constante de restricción de altura de cada fila.


Asumiendo que su celular se ve así:

enter image description here

  • ha agregado un UIView a la celda (vista naranja en mi ejemplo)
  • agregó una etiqueta y un botón a UIView
  • establecer restricciones iniciales, finales, superiores e inferiores para la vista
  • agregó una restricción de altura a la vista
  • conectado IBOutlets y un IBAction para tocar el botón dentro de la clase de celda
  • configure su clase de tabla para UITableViewAutomaticDimension

Entonces esto debería ser un ejemplo de trabajo. Cada vez que toca un botón, la restricción de Altura en esa celda aumentará en 20 puntos. No es necesario llamar a reload nada ...

class TypicalCell: UITableViewCell {

    @IBOutlet weak var theLabel: UILabel!

    @IBOutlet weak var viewHeightConstraint: NSLayoutConstraint!

    var btnAction: (() -> ())?

    @IBAction func didTap(_ sender: Any) {
        btnAction?()
    }

}

class TypicalTableViewController: UITableViewController {

    // 2-D array of Row Heights
    // 4 sections, with 4, 2, 6 and 3 rows
    // all initialized to 40.0
    var rowHeights: [[CGFloat]] = [
        [40.0, 40.0, 40.0, 40.0],
        [40.0, 40.0],
        [40.0, 40.0, 40.0, 40.0, 40.0, 40.0],
        [40.0, 40.0, 40.0]
    ]

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.rowHeight = UITableViewAutomaticDimension
        tableView.estimatedRowHeight = 40.0

    }

    override func numberOfSections(in tableView: UITableView) -> Int {
        return rowHeights.count
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return rowHeights[section].count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Typical", for: indexPath) as! TypicalCell

        // Configure the cell...
        cell.theLabel.text = "\(indexPath)"

        // cells are reused, so set the cell's Height constraint every time
        cell.viewHeightConstraint.constant = rowHeights[indexPath.section][indexPath.row]

        // "call back" closure
        cell.btnAction = {
            // increment the value in our DataSource
            self.rowHeights[indexPath.section][indexPath.row] += 20
            // tell tableView it's being updated
            tableView.beginUpdates()
            // set the cell's Height constraint to the incremented value
            cell.viewHeightConstraint.constant = self.rowHeights[indexPath.section][indexPath.row]
            // tell tableView we're done updating - this will trigger an auto-layout pass
            tableView.endUpdates()
        }

        return cell
    }

}
1
DonMag 21 oct. 2017 a las 15:37

Puede usar el siguiente código para recargar la altura de la celda sin volver a cargar todos los datos:

tableView.beginUpdates()
tableView.endUpdates()
4
bizkhit 21 oct. 2017 a las 12:04

Intente recargar la Sección:

self.tableView.reloadSections(IndexSet(integer: sender.tag), with: .automatic)
1
Martin Muldoon 21 oct. 2017 a las 10:09