Swift:StackView内嵌TableView调整高度后仅显示部分数组数据
问题原因
- viewWillLayoutSubviews 调用时机早于 instructionsTV 内容布局完成的时机:你在该方法中读取 contentSize.height 时,instructionsTV 的 cell 还没完成全部渲染,拿到的高度是不完整的,最终赋值给高度约束的数值偏小,就会导致后面的 cell 显示不出来。
- 数据赋值后没有主动触发 TableView 重新布局以及高度更新:你目前没有在 TableView 刷新数据之后重新计算高度的逻辑。
- 你在 viewWillLayoutSubviews 中错误调用了
super.updateViewConstraints(),没有调用父类对应生命周期方法,也会导致布局计算异常。
修复方案
1. 关闭 TableView 估算高度避免 contentSize 计算偏差
在 setupView 方法中添加以下配置:
// 关闭自动估算高度,强制用实际渲染的高度计算contentSize ingredientsTV.estimatedRowHeight = 0 instructionsTV.estimatedRowHeight = 0 // 关闭安全区自动缩进避免多余高度 ingredientsTV.contentInsetAdjustmentBehavior = .never instructionsTV.contentInsetAdjustmentBehavior = .never
2. 封装独立的高度更新方法
private func updateTableViewHeights() { // 先强制TableView完成全部内容渲染,拿到准确的contentSize ingredientsTV.layoutIfNeeded() instructionsTV.layoutIfNeeded() // 更新高度约束 ingredientsTVHeight.constant = ingredientsTV.contentSize.height instructionsTVHeight.constant = instructionsTV.contentSize.height // 触发父布局(StackView)同步更新 view.layoutIfNeeded() }
3. 数据准备完成后主动触发刷新和高度更新
在 setupView 方法末尾添加代码,确保 TableView 加载完数据后重新计算高度:
ingredientsTV.reloadData() instructionsTV.reloadData() updateTableViewHeights()
4. 修正 viewWillLayoutSubviews 逻辑
override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() self.ingredientsTV.contentInset = UIEdgeInsets(top: 0, left: -20, bottom: 0, right: 0) self.instructionsTV.contentInset = UIEdgeInsets(top: 0, left: -20, bottom: 0, right: 0) updateTableViewHeights() }
额外校验点
- 确认 InstructionsCell 里的 instructionsLbl 已设置
numberOfLines = 0,且上下左右约束完整,可根据文本内容自动撑开 cell 高度 - 确认 StackView 轴方向为 vertical,两个 TableView 的高度约束优先级设置为 999,避免布局冲突
内容的提问来源于stack exchange,提问作者karl mcgeough
相关产品推荐
相关产品推荐

