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

点击按钮添加动态高度UITextView,ScrollView内容尺寸适配问题

解决思路与实现方案

嘿,我来帮你搞定这个问题!你现在的核心痛点是嵌套的UITableView和外层UIScrollView的高度联动,还有UITextView的自动增高要层层传递下去。其实只要把每个环节的自动布局和动态更新逻辑理顺,就能完美解决,下面一步步来:

1. 先搞定UITextView的自动增高

首先每个单元格里的UITextView必须关闭滚动(isScrollEnabled = false),这样它才会根据内容自动撑开高度。然后我们需要监听它的内容变化,触发后续的高度更新:

自定义单元格代码

class TextViewCell: UITableViewCell, UITextViewDelegate {
    @IBOutlet weak var textView: UITextView!
    
    // 定义一个回调,用来通知外部内容变化了
    var onHeightChanged: (() -> Void)?
    
    override func awakeFromNib() {
        super.awakeFromNib()
        textView.isScrollEnabled = false
        textView.delegate = self
        // 给TextView加个内边距,让文字不贴边
        textView.textContainerInset = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
    }
    
    func textViewDidChange(_ textView: UITextView) {
        // 强制更新TextView布局,确保高度计算准确
        textView.layoutIfNeeded()
        // 通知外部高度变化了
        onHeightChanged?()
    }
}

2. 让UITableView自动适配内容高度

因为你把UITableView的滚动关了,它就变成了一个“自适应高度的容器”。我们需要给它加一个高度约束,然后每次内容变化时更新这个约束的数值:

ViewController里的关键设置

首先在Storyboard里给UITableView加一个高度约束,并用IBOutlet关联到代码里(比如叫tableViewHeightConstraint),然后做这些配置:

class ViewController: UIViewController {
    @IBOutlet weak var scrollView: UIScrollView!
    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var tableViewHeightConstraint: NSLayoutConstraint!
    
    // 存储每个TextView的内容,作为TableView的数据源
    var textItems: [String] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
        tableView.register(TextViewCell.self, forCellReuseIdentifier: "TextViewCell")
        
        // 关闭TableView滚动
        tableView.isScrollEnabled = false
        // 开启自动行高计算
        tableView.rowHeight = UITableView.automaticDimension
        // 必须设置预估行高,否则automaticDimension不生效
        tableView.estimatedRowHeight = 100
    }
    
    // 点击添加按钮的方法
    @IBAction func addTextViewButtonTapped(_ sender: UIButton) {
        textItems.append("")
        tableView.reloadData()
        // 更新TableView的高度
        updateTableViewHeight()
    }
    
    // 更新TableView高度的工具方法
    private func updateTableViewHeight() {
        // 必须等TableView完成内容更新后再计算高度,所以用async
        DispatchQueue.main.async {
            self.tableViewHeightConstraint.constant = self.tableView.contentSize.height
            // 强制更新布局,让变化生效
            self.view.layoutIfNeeded()
        }
    }
}

3. 绑定数据源并处理高度联动

在TableView的代理方法里,把回调绑定上,这样当用户输入文字时,会触发单元格高度更新,进而更新TableView和外层ScrollView:

extension ViewController: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return textItems.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "TextViewCell", for: indexPath) as! TextViewCell
        cell.textView.text = textItems[indexPath.row]
        
        // 绑定高度变化的回调
        cell.onHeightChanged = { [weak self] in
            guard let self = self else { return }
            // 先更新数据源
            self.textItems[indexPath.row] = cell.textView.text
            // 让TableView重新计算当前行的高度(用begin/endUpdates比reloadRows更高效)
            tableView.beginUpdates()
            tableView.endUpdates()
            // 更新TableView的整体高度
            self.updateTableViewHeight()
        }
        
        return cell
    }
}

4. 外层ScrollView的布局关键

最后要确保外层UIScrollView的自动布局是正确的:

  • 给ScrollView设置top、leading、trailing、bottom约束到父视图的边缘
  • 给TableView设置top、leading、trailing、bottom约束到ScrollView的边缘
  • 给TableView加一个width约束,等于ScrollView的宽度(避免出现横向滚动)

这样ScrollView会自动根据子视图的高度计算contentSize,不需要手动设置。

几个注意点

  • 一定要给TableView设置estimatedRowHeight,否则UITableView.automaticDimension不会生效
  • 单元格里的UITextView必须和contentView有完整的约束(上下左右都绑定),不能有布局歧义
  • 在textViewDidChange里调用beginUpdates()和endUpdates(),能让TableView只更新当前行的高度,性能更好

这样一套配置下来,点击添加按钮会新增带TextView的单元格,输入文字时TextView自动增高,单元格高度跟着调整,TableView的高度也会自动适配,外层ScrollView的内容尺寸也会同步更新,完全满足你的需求!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:14:06