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

Swift开发iOS14设备下UITextView高度修改后UI未更新问题求解

iOS14 UITextView修改高度后UI未同步更新问题修复

问题根因

  • iOS14对UITextView的布局刷新逻辑做了系统级调整,当控件同时存在自动布局约束和手动frame修改操作时,系统会优先以约束计算结果为准,直接覆盖手动修改的frame值。iOS13及更低版本对混合布局的容错更高,会优先取最后设置的frame值,因此问题仅出现在iOS14设备上。
  • 你当前代码同时混用「手动修改UITextView frame」和「触发父视图约束更新」两种布局逻辑,触发了iOS14的布局优先级判断规则,导致修改的frame被自动重置。

修复方案

方案1:全量使用自动布局实现(推荐)

不要手动修改frame,通过修改高度约束的constant值实现自适应,适配所有系统版本:

// 先通过xib/纯代码给inputTextView添加高度约束,关联为成员属性
@IBOutlet weak var textViewHeightConstraint: NSLayoutConstraint!

func textViewDidChange(_ textView: UITextView) {
    let size = textView.sizeThatFits(CGSize(width: textView.frame.width, height: CGFloat(MAXFLOAT)))
    textViewHeightConstraint.constant = size.height
    // 触发父视图布局刷新,可加动画让过渡更自然
    UIView.animate(withDuration: 0.2) {
        self.messageInputContainerView.layoutIfNeeded()
    }
}

方案2:坚持使用frame布局的适配方案

如果业务逻辑需要保留frame修改方式,禁止触发父视图约束更新,直接强制刷新布局即可:

func textViewDidChange(_ textView: UITextView) {
    let size = textView.sizeThatFits(CGSize(width: textView.frame.width, height: CGFloat(MAXFLOAT)))
    var frame = textView.frame
    frame.size.height = size.height
    textView.frame = frame
    // 强制刷新当前控件和父视图布局,不要调用setNeedsUpdateConstraints
    textView.layoutIfNeeded()
    self.messageInputContainerView.layoutIfNeeded()
}

注意事项

  • 计算高度前请确保UITextView的isScrollEnabled属性为false,否则sizeThatFits会返回固定高度而非内容实际高度
  • 不要混用frame修改和自动布局约束更新操作,两种布局方式二选一即可,避免系统布局优先级判断异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 15:18:02