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

XIB加载的UITextView如何实现类似WhatsApp的随内容自适应高度效果?

问题根因及修复方案

存在的核心问题

  • 你已经在XIB中关联了高度约束的IBOutlet textViewHC,但又在viewDidLoad中额外新增了一个高度为52的高度约束,两个高度约束冲突导致高度修改不生效
  • 遍历所有约束修改高度的逻辑冗余,也可能误改其他约束,直接操作已关联的textViewHC即可
  • 修改高度约束后没有触发父视图的布局刷新,你的输入视图加载在容器视图中,必须通知父视图更新布局才能让整体容器同步适配高度
  • 初始状态没有关闭isScrollEnabled,初始状态下如果没关闭的话自适应逻辑不会生效

修改后的代码

class InputTextViewController: UIViewController{
  
  @IBOutlet weak var inputTitle: UILabel!
  @IBOutlet weak var border: UIView!
  @IBOutlet weak var inputTextView: UITextView!
  @IBOutlet weak var underText: UILabel!
  @IBOutlet weak var underLine: UIView!
  
  @IBOutlet weak var textViewHC: NSLayoutConstraint!
  // 高度常量统一配置,方便后续修改
  private let maxTextViewHeight: CGFloat = 100.0
  private let minTextViewHeight: CGFloat = 52.0

  override func viewDidLoad() {
        super.viewDidLoad()
    // 删掉多余的新增高度约束,直接用已有的IBOutlet约束设置初始高度
    textViewHC.constant = minTextViewHeight
    self.inputTextView.delegate = self
    // 初始关闭滚动,开启自适应
    inputTextView.isScrollEnabled = false
    inputTextView.translatesAutoresizingMaskIntoConstraints = false
    }
}
extension InputTextViewController: UITextViewDelegate{
  
  func textViewDidChange(_ textView: UITextView) {
    let size = CGSize(width: inputTextView.frame.size.width, height: .infinity)
    let estimatedSize = inputTextView.sizeThatFits(size)
    
    let targetHeight = min(estimatedSize.height, maxTextViewHeight)
    // 高度无变化时跳过更新,避免重复布局
    guard textViewHC.constant != targetHeight else { return }
    
    textViewHC.constant = targetHeight
    // 超过最大高度开启滚动,否则关闭
    inputTextView.isScrollEnabled = estimatedSize.height >= maxTextViewHeight
    // 触发当前视图和父容器的布局更新,加动画更流畅
    UIView.animate(withDuration: 0.2) { [weak self] in
      self?.view.layoutIfNeeded()
      self?.parent?.view.layoutIfNeeded()
    }
  }
}

额外需要检查的配置

  • 确认你的容器视图对InputTextViewController的根视图的约束是四边贴合,没有固定高度约束,否则容器不会随输入视图高度变化
  • 确认inputTextView在XIB中的上下左右约束已经正确关联到父视图,只保留关联到textViewHC的那一个高度约束即可,删除其他多余的高度约束
  • 如果输入框有内边距需求,可以统一设置inputTextView.textContainerInset调整,不要用额外的空白约束修改高度

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 21:36:02