So I have a scrollView
, inside that scrollView
is a stackView
that contains every views
in the screen.
The problem is my stackView
has many hide-able views
so I need to adjust my containsVieww's height
base on my stackView's height
my psuedo code should be like this :
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
print(stackView.bounds.height)
// do logic to change contentView size here
}
func setupView(){
scrollView.topAnchor.constraint(equalTo: guide.topAnchor).isActive = true
scrollView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
scrollView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
scrollView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
scrollView.backgroundColor = .white
scrollView.contentSize = CGSize(width: view.frame.width, height: view.frame.height)
scrollView.addSubview(stackView)
stackView.setArrangedSubView(views: [label1, label 2, label 3, label 4, ..., label n]
[label1, label 2, label 3].isHidden = true
}
func onHitButton(){
if isHidden {
[label1, label 2, label 3].isHidden = false
isHidden = false
} else {
[label1, label 2, label 3].isHidden = true
isHidden = true
}
print(stackView.bounds.height) // still return the ex height
}
Here is the problem:
On first init
, my [label1,2,3].isHidden = true
, my stackViewHeight
is 500
When my onHitButton
is called, my [label1,2,3].isHidden = false
, my stackViewHeight
is still 500
but the screen displays correctly, those labels
are visible now and my stackView
is stretched. And of course my scrollView
is not displays correctly.
Then I hit my onHitButton
again, those labels
are hidden, my stackView
is shrink on screen but the stackViewHeight
returned 850
?
It's supposed to be the other way around.
I also tried to print
the height
on another button
call and it return the right height
? Seem like viewDidLayoutSubviews
called too early.
To sum it up: stackView
return the height before it resize it self
CodePudding user response:
Use auto-layout to constrain the stack view to the scroll view's Content Layout Guide:
scrollView.addSubview(stackView)
stackView.translatesAutoresizingMaskIntoConstraints = false
// reference to scrollView's Content Layout Guide
let cGuide = scrollView.contentLayoutGuide
// reference to scrollView's Frame Layout Guide
let fGuide = scrollView.frameLayoutGuide
NSLayoutConstraint.activate([
// constrain stackView to scrollView's Content Layout Guide
stackView.topAnchor.constraint(equalTo: cGuide.topAnchor),
stackView.leadingAnchor.constraint(equalTo: cGuide.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: cGuide.trailingAnchor),
stackView.bottomAnchor.constraint(equalTo: cGuide.bottomAnchor),
// constrain stackView's Width to scrollView's Frame Layout Guide
stackView.widthAnchor.constraint(equalTo: fGuide.widthAnchor),
])
This will completely avoid the need to ever set .contentSize
-- it will all be handled by auto-layout.