You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UIStackView在viewDidLayoutSubviews及显隐切换时返回旧高度如何解决?

问题根本原因
  • 修改UIStackView子视图的isHidden属性后,Auto Layout不会立刻触发视图重绘,而是会等待当前Runloop周期结束后才执行布局更新,因此你在修改属性后立刻读取bounds.height拿到的是布局更新前的旧值。
  • 你当前手动设置scrollView.contentSize的逻辑不符合Auto Layout规范,系统无法自动根据stackView的大小同步滚动区域。
解决方案

1. 修正ScrollView与StackView的约束逻辑

不要手动设置contentSize,使用UIScrollView的布局引导自动计算滚动区域,代码如下:

func setupView(){
    scrollView.translatesAutoresizingMaskIntoConstraints = false
    stackView.translatesAutoresizingMaskIntoConstraints = false
    // scrollView 约束到父视图
    scrollView.topAnchor.constraint(equalTo: guide.topAnchor).isActive = true
    scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
    scrollView.backgroundColor = .white
    
    scrollView.addSubview(stackView)
    // stackView 约束到scrollView的content引导
    stackView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor).isActive = true
    stackView.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor).isActive = true
    stackView.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor).isActive = true
    stackView.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor).isActive = true
    // stackView宽度和scrollView可视区域宽度一致
    stackView.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor).isActive = true
    
    stackView.setArrangedSubviews(views: [label1, label2, label3, label4, ..., labeln])
    [label1, label2, label3].forEach { $0.isHidden = true }
}

2. 强制触发布局更新后读取高度

修改子视图隐藏状态后,调用layoutIfNeeded()强制触发立即布局,就能拿到最新的高度:

func onHitButton(){
    let targetLabels = [label1, label2, label3]
    targetLabels.forEach { $0.isHidden = isHidden }
    isHidden.toggle()
    // 强制触发立即布局更新
    view.layoutIfNeeded()
    // 此时打印的就是最新高度
    print(stackView.bounds.height)
}

3. 优化viewDidLayoutSubviews逻辑

约束配置正确后,系统会自动同步scrollView.contentSize,不需要你手动修改。如果需要在布局完成后执行自定义逻辑,可以直接在viewDidLayoutSubviews里操作,此时读取的stackView.bounds已经是最新值,注意避免重复执行冗余操作即可。

内容的提问来源于stack exchange,提问作者bao le

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 11:48:04