修改NSLayoutConstraint常量后UIView未即时刷新问题求助
UITableView点击切换高度不即时刷新的解决方案
我太懂这种憋屈的感觉了——改了约束又调frame,结果视图就是不跟着变,非得等用户再动一下才更新,真的头大!咱们先拆解问题根源,再一步步解决:
问题出在哪?
你现在同时修改了frame和Auto Layout约束,这在Auto Layout环境下是完全冲突的!Auto Layout的核心逻辑就是靠约束自动计算控件的frame,你手动改的frame会被约束的计算结果直接覆盖,相当于白忙活一场。而且你只标记了“需要更新约束”,但没有强制系统立即执行布局更新,所以视图才会延迟刷新。
正确解决思路&代码
咱们直接抛弃手动改frame的思路,全程用约束控制高度,再配合强制布局更新,就能实现即时切换:
- 只保留约束控制高度:确保只有
faultViewHeight这一个约束来控制tableView的高度,不要再碰frame; - 修改约束后强制更新布局:修改约束常量后,调用
layoutIfNeeded()让系统立即重新计算布局,还能套个动画让切换更顺滑; - 行高要匹配约束高度:比如收起状态的48对应第一行高度,展开后的115对应所有行总高度,要保证行高设置正确(可以直接用
tableView.rowHeight或者代理方法)。
修改后的代码示例:
// 先更新约束常量 if currentNumber == 1 { currentNumber = 2 faultViewHeight?.constant = 115 } else { currentNumber = 1 faultViewHeight?.constant = 48 } // 强制立即更新布局,加上动画更友好 UIView.animate(withDuration: 0.3) { self.view.layoutIfNeeded() } // 如果需要同步更新行内容,再调用reloadData tblFaults?.reloadData()
为啥之前的方法没用?
- 手动改
frame的操作会被Auto Layout的约束计算直接覆盖,等于做了无用功; setNeedsUpdateConstraints只是告诉系统“约束要更新了”,但不会立即执行布局计算,必须调用layoutIfNeeded()才能让系统马上重新布局;setNeedsDisplay是用来刷新视图绘制内容的,和布局更新完全不相关,所以对你的问题起不到作用。
这样改完之后,点击按钮就能即时看到tableView的高度变化了,还带平滑的动画效果,完美解决延迟刷新的问题!
内容的提问来源于stack exchange,提问作者pz26
相关产品推荐
相关产品推荐

