StackView 在 viewDidLayoutSubviews 返回前高度
Posted
技术标签:
【中文标题】StackView 在 viewDidLayoutSubviews 返回前高度【英文标题】:StackView returns the ex-height in viewDidLayoutSubviews 【发布时间】: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
,我的stackViewHeight
是500
当我的onHitButton
被调用时,我的[label1,2,3].isHidden = false
,我的stackViewHeight
仍然是500
,但屏幕显示正确,那些labels
现在可见,我的stackView
被拉伸。当然我的scrollView
显示不正确。
然后我再次点击我的onHitButton
,那些labels
被隐藏,我的stackView
在屏幕上缩小但stackViewHeight
返回850
?
应该是相反的。
我还尝试在另一个button
呼叫中print
height
并返回正确的height
?好像viewDidLayoutSubviews
调用得太早了。
总结一下:stackView
在它自己调整大小之前返回高度
【问题讨论】:
【参考方案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 决定 Horizontal 滚动大小,Top 和 Bottom + Height 决定 Vertical 滚动大小。在这里,我们使用堆栈视图内容(排列的子视图)来确定它的高度。注释掉 Width 约束线,看看你得到了什么。然后尝试将 Width 约束上的 Constant 设置为 100、500 或 1000,看看你会得到什么。
“我在 stackView 中的最后一个视图总是在 view.BottomAnchor 没有任何空间” ...你的意思是在堆栈底部之后想要一些“空白空间”看法?如果是这样,给底部锚的常数一个负值。例如:stackView.bottomAnchor.constraint(equalTo: cGuide.bottomAnchor, constant: -100.0),
以上是关于StackView 在 viewDidLayoutSubviews 返回前高度的主要内容,如果未能解决你的问题,请参考以下文章
stackView 中的 StackView 不能通过 swift 使用它的间距
如何在 StackView 中展开 UITableView?