ios - Cómo dimensionar un UIStackView según su contenido?
uitableview swift2 (1)
Me gustaría tener un comportamiento similar al de la etiqueta <Table>
HTML, en el sentido en que el marco se clasifica según su contenido.
En mi propio contexto, utilizo UIStackView como la vista de contenido de una UITableViewCell. Como los elementos en la celda son información diversa, la altura resultante de la celda debe ser variable.
Mi estrategia es construir programáticamente una celda como UIStackView con un eje vertical, como en el fragmento de código de la siguiente manera:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
let sv = UIStackView(frame: tableview.frame)
sv.axis = .Vertical
cell.addSubview(sv)
for i in information {
let l = UILabel()
l.text = i
sv.addSubViewAndArrange(l)
}
return cell
}
Lamentablemente, el tamaño de la celda no se ajusta al contenido y, como resultado, tengo que configurar la altura de la celda de la siguiente manera:
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return cellHeight // a constant
}
¿Cómo podría arreglar eso?
UIStackView
está diseñado para aumentar su tamaño de acuerdo con el contenido. Para que eso funcione, debe configurar las restricciones entre UIStackView
y UITableViewCell
. Por ejemplo, así es como se ven las restricciones en el constructor de interfaces:
Si le gusta establecer restricciones en el código, eso debería funcionar también.
Para demostrar que esto funcionará, tengo esto para la función cellForRowAt
. Básicamente, pone un número de UILabel
dentro de stackView
y el recuento de etiquetas depende del número de fila.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TableviewCell", for: indexPath) as! TableviewCell
for i in 1...indexPath.row + 1 {
let label = UILabel()
label.text = "Row /(indexPath.row), Label /(i)"
cell.stackView.addArrangedSubview(label)
}
return cell
}
Aquí esta el resultado final:
https://github.com/yzhong52/AutosizeStackview
Editar
Para aquellos que les gusta hacer todo en código en lugar de constructor de interfaz:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TableviewCell", for: indexPath)
let stackview = UIStackView()
stackview.translatesAutoresizingMaskIntoConstraints = false
stackview.axis = .vertical
cell.addSubview(stackview)
NSLayoutConstraint.activate([
stackview.leadingAnchor.constraint(equalTo: cell.leadingAnchor, constant: 10),
stackview.trailingAnchor.constraint(equalTo: cell.trailingAnchor, constant: -10),
stackview.topAnchor.constraint(equalTo: cell.topAnchor, constant: 10),
stackview.bottomAnchor.constraint(equalTo: cell.bottomAnchor, constant: -10),
])
for i in 1...indexPath.row + 1 {
let label = UILabel()
label.text = "Row /(indexPath.row), Label /(i)"
stackview.addArrangedSubview(label)
}
return cell
}
https://github.com/yzhong52/AutosizeStackview/tree/code_instead_of_interface_builder