【问题标题】:StackView returns the ex-height in viewDidLayoutSubviewsStackView 在 vi​​ewDidLayoutSubviews 返回前高度
【发布时间】:2021-10-07 12:34:05
【问题描述】:

所以我有一个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 返回850

应该是相反的。

我还尝试在另一个button 呼叫中print height 并返回正确的height?好像viewDidLayoutSubviews 调用得太早了。

总结一下:stackView 在它自己调整大小之前返回高度

【问题讨论】:

    标签: swift uistackview viewdidlayoutsubviews


    【解决方案1】:

    使用自动布局将堆栈视图约束到滚动视图的内容布局指南

        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 的需要——它将全部由自动布局处理。

    【讨论】:

    • 你为什么要给前导和尾随锚,为什么已经有一个widthAnchor?除了那个,一切都很完美。谢谢
    • 我发现的另一个小问题是我似乎无法调整bottomAnchor 常量,我在stackView 中的最后一个视图的底部总是在view.BottomAnchor 没有任何空间。我试图在 stackView bottomAnchor 和 scrollView bottomAnchor 中都给出常量,但它不起作用。但是给topAnchor constant 工作。奇怪
    • Leading / Trailing / Width Anchors ...这就是滚动视图的工作方式。 Lead and Trailing + Width 决定 Horizo​​ntal 滚动大小,Top 和 Bottom + Height 决定 Vertical 滚动大小。在这里,我们使用堆栈视图内容(排列的子视图)来确定它的高度。注释掉 Width 约束线,看看你得到了什么。然后尝试将 Width 约束上的 Constant 设置为 100、500 或 1000,看看你会得到什么。
    • “我在 stackView 中的最后一个视图总是在 view.BottomAnchor 没有任何空间” ...你的意思是在堆栈底部之后想要一些“空白空间”看法?如果是这样,给底部锚的常数一个负值。例如:stackView.bottomAnchor.constraint(equalTo: cGuide.bottomAnchor, constant: -100.0),
    猜你喜欢
    • 2018-04-08
    • 2017-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-30
    • 1970-01-01
    相关资源
    最近更新 更多