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
相关产品推荐
相关产品推荐

