StackView returns viewDidLayoutSubviews 中的前高度

StackView returns the ex-height in viewDidLayoutSubviews

所以我有一个 scrollView,里面的 scrollView 是一个 stackView,它包含屏幕中的每个 views

问题是我的 stackView 有很多可隐藏的 views 所以我需要根据我的 stackView's height

调整我的 containsVieww's height

我的伪代码应该是这样的:


 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
}

这是问题所在:

首先 init,我的 [label1,2,3].isHidden = true,我的 stackViewHeight500

当我的 onHitButton 被调用时,我的 [label1,2,3].isHidden = false,我的 stackViewHeight 仍然是 500 但屏幕显示正确,那些 labels 现在是可见的我的 stackView 被拉长了。当然,我的 scrollView 显示不正确。

然后我再次点击 onHitButton,那些 labels 被隐藏了,我的 stackView 在屏幕上缩小了,但是 stackViewHeight returned 850?

应该是反过来的。

我还尝试在另一个 button 调用中 print height,它 return 正确 height?好像 viewDidLayoutSubviews 叫得太早了。

总结一下:stackView return 自身调整大小前的高度

使用自动布局将堆栈视图限制为滚动视图的内容布局指南

    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),
        
    ])
    

这将完全避免设置 .contentSize -- 它将全部由自动布局处理。