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

如何正确实现UITextView高度随内容自适应调整?

问题根因

两个方案的核心错误都是错误修改了translatesAutoresizingMaskIntoConstraints属性,打断了Auto Layout的正常布局流程:

第一种方案问题

代码如下:

func textViewDidChange(_ textView: UITextView) {
    self.comments.translatesAutoresizingMaskIntoConstraints = true
    self.comments.sizeToFit()
    self.comments.isScrollEnabled = false
}

直接调用sizeToFit()时,因为没有给TextView固定宽度,系统会按内容计算最小可容纳尺寸,最终宽度被压缩到仅能容纳单个字符,就会出现每行只能输入1个字符的问题。

第二种方案问题

代码如下:

func textViewDidChange(_ textView: UITextView) {
    self.comments.translatesAutoresizingMaskIntoConstraints = true
    self.comments.isScrollEnabled = false
    let fixedWidth = passedOut.frame.size.width
    let newSize = comments.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
    comments.frame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
}

viewDidLoad阶段视图尚未完成约束布局,此时passedOut的宽度还未计算为约束设定的正确值,提前把translatesAutoresizingMaskIntoConstraints设为true后,系统会用当前错误的宽度生成frame,导致首屏TextView宽度偏窄。等开始输入触发回调时,视图已经完成首轮布局,passedOut宽度正确,计算出的TextView尺寸就恢复正常了。
viewDidLoad阶段异常效果如下:
第二种方案viewDidLoad阶段效果截图

正确实现方案

全程使用Auto Layout控制尺寸,不要随意修改translatesAutoresizingMaskIntoConstraints为true(纯约束布局下这个属性保持默认false即可),实现步骤:

  1. 给comments这个UITextView设置和passedOut一致的leading、trailing约束,再加一个高度约束,将其关联为属性commentsHeightConstraint
  2. 完成基础初始化配置:
override func viewDidLoad() {
    super.viewDidLoad()
    comments.isScrollEnabled = false
    // 其余业务配置
}
  1. 首屏布局完成后更新一次高度,解决初始加载尺寸不对的问题:
override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    updateCommentsHeight()
}
  1. 输入内容时实时更新高度:
func textViewDidChange(_ textView: UITextView) {
    updateCommentsHeight()
}
  1. 封装高度计算方法:
func updateCommentsHeight() {
    let calculateSize = CGSize(width: comments.bounds.width, height: .greatestFiniteMagnitude)
    let targetHeight = comments.sizeThatFits(calculateSize).height
    // 如果需要设置最小高度,可改为 commentsHeightConstraint.constant = max(targetHeight, 最小高度值)
    commentsHeightConstraint.constant = targetHeight
    view.layoutIfNeeded()
}
  • 该方案完全通过约束控制尺寸,不会出现宽度计算错误、首屏布局异常的问题
  • 不要在输入回调中切换布局模式(约束/frame),会导致布局状态混乱

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 21:09:18