Estoy buscando construir una vista que crecerá a medida que se le agreguen subvistas. Al principio, la altura será cero, luego debería crecer a medida que agregue subvistas hasta que alcance un tamaño máximo, y luego quiero que se pueda desplazar.
Si construyo esto usando un UIView dentro de un UIScrollView y configuro las restricciones de arriba a abajo manualmente, funciona como se esperaba. Sin embargo, siento que esto debería ser posible usando un UIStackView, pero cuando lo intento, la vista de desplazamiento no crece o el tamaño del contenido del scrollView se atasca en la altura máxima y no se desplaza. He estado jugando con esto por un tiempo y creo que en realidad podría ser un error con UIStackView y Autolayout, pero espero que me haya perdido algo. Envolver el UIStackView en un contenedor UIView no ayuda.
Aquí hay un controlador de vista completo que muestra el problema (tocar en cualquier lugar agrega etiquetas a la vista de desplazamiento)
import UIKit class DumbScrollStack: UIViewController { let stack = UIStackView() let scrollView = UIScrollView() override func viewDidLoad() { super.viewDidLoad() //Setup view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(addLabel))) stack.axis = .vertical view.backgroundColor = .blue scrollView.backgroundColor = .red //Add scroll view and setup position view.addSubview(scrollView) scrollView.translatesAutoresizingMaskIntoConstraints = false scrollView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true scrollView.topAnchor.constraint(equalTo: view.centerYAnchor).isActive = true scrollView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true //Set maximum height scrollView.heightAnchor.constraint(lessThanOrEqualToConstant: 100).isActive = true //add stack scrollView.addSubview(stack) stack.translatesAutoresizingMaskIntoConstraints = false //setup scrollView content size constraints stack.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true stack.leftAnchor.constraint(equalTo: scrollView.leftAnchor).isActive = true stack.rightAnchor.constraint(equalTo: scrollView.rightAnchor).isActive = true stack.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true stack.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true // Keep short if stack height is lower than scroll height // With this constraint the scrollView grows as expected, but doesn't scroll when it goes over 100px // Without this constraint the scrollView is always 100px tall but it does scroll let constraint = scrollView.heightAnchor.constraint(equalTo: stack.heightAnchor) constraint.priority = UILayoutPriority(rawValue: 999) constraint.isActive = true addLabel() } @objc func addLabel() { let label = UILabel() label.backgroundColor = .gray label.text = "Hello" stack.addArrangedSubview(label) } }Agrega esto
label.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 1000), for: .vertical)o comenta este bloque
let constraint = scrollView.heightAnchor.constraint(equalTo: stack.heightAnchor) constraint.priority = UILayoutPriority(rawValue: 999) constraint.isActive = trueo haga que sea inferior a 750 (la compresión vertical predeterminada de la etiqueta)
constraint.priority = UILayoutPriority(rawValue: 749)el problema es que la prioridad de compresión vertical de la etiqueta es inferior a 999, lo que siempre hace que la pila sea igual a la altura de la vista de desplazamiento, por lo tanto, no hay desplazamiento
¿Ha considerado usar un UICollectionView ? Suena como lo que estás tratando de reconstruir.
Asegúrese de establecer "Desplazamiento habilitado" en verdadero y establezca la dirección de desplazamiento.