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

Swift:如何根据UITextView内容动态设置UIScrollView高度?

嘿,这个问题我之前踩过坑!核心原因是在viewDidLoad里视图还没完成最终布局——UITextView刚设置完文本,还没来得及重新计算内容高度,这时候你拿到的尺寸还是初始默认值,根本不是文本更新后的真实高度。下面给你一套靠谱的解决思路和代码示例:

解决步骤

1. 先把UITextView的基础配置搞对

要让UITextView能动态撑开高度,必须先关闭它的内部滚动功能,不然它会保持固定高度,内容在内部滚动,不会影响外部布局:

textView.isScrollEnabled = false
// 可选:去掉UITextView默认的内边距,避免计算高度时出现偏差
textView.contentInset = .zero
textView.textContainerInset = .zero
textView.textContainer.lineFragmentPadding = 0

2. 选对计算高度的时机

别在viewDidLoad里急着算高度,推荐两个可靠的时机:

  • 设置完文本后,手动触发视图布局更新,再计算
  • 在viewDidLayoutSubviews里计算(这个方法会在视图完成布局后调用,尺寸绝对准确)

3. 编写动态更新ScrollView高度的函数

假设你用Auto Layout管理布局,给ScrollView加了一个高度约束的IBOutlet,或者直接依赖内容视图的自动撑开效果:

代码示例

// 视图控制器里的属性关联
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var textView: UITextView!
@IBOutlet weak var scrollViewHeightConstraint: NSLayoutConstraint! // ScrollView的高度约束

override func viewDidLoad() {
    super.viewDidLoad()
    
    // 初始化文本
    textView.text = "这里是你的动态文本内容,可以是从接口拉取的长文本,也可以是用户输入的内容..."
    // 配置UITextView
    textView.isScrollEnabled = false
    textView.contentInset = .zero
    textView.textContainerInset = .zero
    
    // 手动触发布局,确保文本渲染完成后再计算高度
    textView.layoutIfNeeded()
    updateScrollViewHeight()
}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    // 每次布局完成都更新一次,确保旋转屏幕或视图变化时高度依然准确
    updateScrollViewHeight()
}

// 核心更新函数
func updateScrollViewHeight() {
    // 计算UITextView的真实内容高度:用sizeThatFits给一个无限高的宽度限制,让它返回适配的高度
    let textViewRealHeight = textView.sizeThatFits(CGSize(
        width: textView.bounds.width,
        height: CGFloat.greatestFiniteMagnitude
    )).height
    
    // 如果ScrollView里还有其他子视图,需要把所有子视图的高度加起来(比如顶部标题、底部按钮等)
    // 这里假设只有UITextView,直接用它的高度即可;如果有contentView,直接取contentView的高度更方便
    let totalContentHeight = textViewRealHeight
    
    // 更新ScrollView的高度约束
    scrollViewHeightConstraint.constant = totalContentHeight
    // 同时更新ScrollView的contentSize(如果不用Auto Layout管理内容的话)
    scrollView.contentSize = CGSize(width: scrollView.bounds.width, height: totalContentHeight)
}

进阶:用Auto Layout自动撑开ScrollView

更省心的方式是给ScrollView套一个contentView,把所有子视图(包括UITextView)放在contentView里,然后给contentView设置以下约束:

  • contentView的top/leading/trailing/bottom 与 scrollView的contentLayoutGuide对齐
  • contentView的width 与 scrollView的frameLayoutGuide宽度相等

这样只要子视图的约束正确(比如UITextView的top/leading/trailing和contentView对齐,bottom和contentView对齐),当UITextView内容变化时,contentView会自动撑开高度,ScrollView的contentSize也会自动更新,完全不用手动计算高度!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:39:55