简体   繁体   中英

UIStackView in UIScrollView not scrolling

I am having a bit of trouble implementing a UIStackView in a UIScrollView . My view hierarchy looks something like this:

 ┌─────────────────────────────┐
 │ViewController               │
 │┌───────────────────────────┐│
 ││Spacer UIView              ││
 │└───────────────────────────┘│
 │┌───────────────────────────┐│
 ││ UIScrollView              ││
 ││┌─────────────────────────┐││
 │││UIStackView              │││
 │││                         │││
 │││                         │││
 ││└─────────────────────────┘││
 │└───────────────────────────┘│
 │┌───────────────────────────┐│
 ││Spacer UIView              ││
 │└───────────────────────────┘│
 │┌───────────────────────────┐│
 ││UIView with other content  ││
 ││height: 300                ││
 │└───────────────────────────┘│
 └─────────────────────────────┘

I have the spacer views so that the content get's vertically centered, if it is shorter than the full height of the screen. I layout the NSLayoutConstraints as follows V:|-[spacer1]-[scrollview]-[spacer2(==spacer1)]-[footerView]-|

The UIStackView get's filled with UIViews each with a height of 50 (basically a table with rows).

So far so good. As soon as my stack view has more rows than "room", I get an unending stream of error messages stating that the constraint (the height of the individual row) must be broken. The error messages keep on going back and forth with constantly new objects memory id - it basically never finishes. I am assuming that the content height of my scroll view does not get set correctly.

In my viewDidLoad I setup the spacer and scrollview as such:

let spacer1 = UIView()
spacer1.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(spacerView1)
spacerView1.widthAnchor.constraint(equalTo: self.view.widthAnchor).isActive = true

let scroll = UIScrollView()
scroll.translatesAutoresizingMaskIntoConstraints = false
scroll.showsHorizontalScrollIndicator = false
self.view.addSubview(scroll)
scroll.widthAnchor.constraint(equalTo: self.view.widthAnchor).isActive = true

let stack = UIStackView()
stack.axis = .vertical
stack.translatesAutoresizingMaskIntoConstraints = false
stack.alignment = .center
stack.spacing = 2
stack.distribution = .equalSpacing
scroll.addSubview(stack)
stack.topAnchor.constraint(equalTo: scroll.topAnchor).isActive = true
stack.leftAnchor.constraint(equalTo: scroll.leftAnchor).isActive = true
stack.rightAnchor.constraint(equalTo: scroll.rightAnchor).isActive = true
stack.bottomAnchor.constraint(equalTo: scroll.bottomAnchor).isActive = true
stack.widthAnchor.constraint(equalTo: scroll.widthAnchor).isActive = true
stack.heightAnchor.constraint(equalTo: scroll.heightAnchor).isActive = true

In another method which is called from another class, I then add UIViews to the UIStackView simply by adding them like: stack.addArrangedSubview(rowView) .

After adding the UIView to the stack view I resize the scroll view with

extension UIScrollView {
    func resizeScrollViewContentSize() {
        var contentRect = CGRect.zero
        for view in self.subviews {
            contentRect = contentRect.union(view.frame)
        }
        self.contentSize = contentRect.size
    }
}

which gives the constraint breaking errors.

If I delete the height constraint of the stack view, then it collapses and the debug view hierarchy tells me that the height and vertical position of UIStackView are ambiguous. I also tried to simply set scroll.contentSize = stack.frame.size once all the rows were added to the stack view. But that didn't work either. I have also tried to add the rows to the stack view first and then add the stack view to the scroll view. That way the stack view should know its size requirements, but that didn't work either.

As mentioned this works fine, as long as the total height of the rows is smaller than the possible space. As soon as I add one more row or I execute the app on a device with smaller screen size I get Will attempt to recover by breaking constraint <NSLayoutConstraint:0x600000b29fe0 MyApp.RowView:0x7fc571e840f0.height == 50 (active)> .

Basically the scrolling functionality of the UIScrollView is not working with my stack view. How can I force the scroll view to re-calculate the need height for it's content.

What am I missing or doing wrong?

Thanks

To manage with this problem stackView height must be dynamic. Try to set height constraint priority to 750, after subviews did layout, everything must work

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM