swift - 实现tableViewCell高度自适应随cell内部textView高度的变化而变化

实现思路:

1)设置cell的高度为自动计算:UITableView.automaticDimension

2)为cell内部的view控件添加上下约束

如图所示,当cell高度自动计算,且约束添加成功时,cell竖直方向被撑满,这样cell的高度就会随着view控件的高度变化了 。

​​​​​​​实现步骤:

步骤一(自定义tableViewCell,设置约束!!!这里只使用一个label标题和一个textView模拟):创建TableViewControllerCell.swift文件,并添加如下代码:

// 自定义TableViewCell。以便使用“复用”特性
class TableViewControllerCell: UITableViewCell {
    var titleLabel = UILabel()
    var textView = UITextView()
    
    override init(style: UITableViewCell.CellStyle,reuseIdentifier: String?) {
        super.init(style: .value1,reuseIdentifier: nil)
        
        // 设置label控件
        self.titleLabel.frame = CGRect(x: 20,y: 15,width: 60,height: 20)
        self.titleLabel.backgroundColor = .yellow
        self.contentView.addSubview(self.titleLabel)
        
        // 设置textView控件
        self.textView.frame = CGRect(x: 100,y: 10,width: 100,height: 20)
        self.textView.backgroundColor = .green
        // 设置textView的内容不能滑动
        self.textView.isScrollEnabled = false
        self.contentView.addSubview(self.textView)
        
        // 为textView添加约束
        self.constraintsTextView()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // 为textView添加约束
    func constraintsTextView() {
        // 将textView的autolayout设置为失效,否则下面约束不起作用
        self.textView.translatesAutoresizingMaskIntoConstraints = false
        
        // 设置顶部约束
        self.textView.superview?.addConstraint(NSLayoutConstraint(item: self.textView,attribute: .topMargin,relatedBy: .equal,toItem: self.contentView,multiplier: 1.0,constant: 10))
        // 设置底部约束
        self.textView.superview?.addConstraint(NSLayoutConstraint(item: self.textView,attribute: .bottomMargin,constant: -10))
        // 设置左侧约束
        self.textView.superview?.addConstraint(NSLayoutConstraint(item: self.textView,attribute: .leftMargin,constant: 100))
        // 设置宽度约束
        self.textView.addConstraint(NSLayoutConstraint(item: self.textView,attribute: .width,toItem: nil,attribute: .notAnAttribute,constant: 200))
        // 设置高度约束
        self.textView.addConstraint(NSLayoutConstraint(item: self.textView,attribute: .height,relatedBy: .greaterThanOrEqual,constant: 30))  
    }
    
}

步骤二(创建tableView控件):创建TableViewController.swift文件,并添加如下代码,这里一定要设置tableview的代理和数据源。cell复用机制的使用请移步 UITableViewCell复用机制的使用步骤 一文。

import UIKit

class TableViewController: UIViewController {
    private var tableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 添加tableView控件
        self.tableView = UITableView(frame: CGRect(x: 0,y: 0,width: self.view.frame.width,height: self.view.frame.height))
        // 注册tableviewCell复用池
        self.tableView.register(TableViewControllerCell.self,forCellReuseIdentifier: "cell")
        // 设置代理
        self.tableView.delegate = self
        // 设置数据源
        self.tableView.dataSource = self
        
        self.view.addSubview(self.tableView)
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(true)
        
        // 刷新tableView的数据
        self.tableView.reloadData()
    }
    
}

步骤三(设置cell的高度为自动计算UITableView.automaticDimension!!!):tableView各项设置的代码如下,注意在cellForRowAt方法中设置tetxview的代理。

extension TableViewController: UITableViewDelegate,UITableViewDataSource {
    
    // 设置tableView每行的预估高度
    func tableView(_ tableView: UITableView,estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return 55
    }
    
    // 设置tableView每行的高度自适应
    func tableView(_ tableView: UITableView,heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
    }

    // 设置tableView的Section数量
    func numberOfSections(in tableView: UITableView) -> Int {
        return 2
    }

    // 设置tableView每一个section的行数
    func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
        return 1
    }

    // 设置tableView每一行的内容
    func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // 复用tableViewCell
        let cell = self.tableView.dequeueReusableCell(withIdentifier: "cell",for: indexPath) as! TableViewControllerCell
        
        // 设置每一行的标题
        cell.titleLabel.text = "第" + String(indexPath.section) + "行"
        // 设置textView的代理
        cell.textView.delegate = self
        
        return cell
    }
    
}

步骤四实现textview高度自适应

// 设置textView高度自适应
extension TableViewController: UITextViewDelegate {
    func textViewDidChange(_ textView: UITextView) {
        // 储存原textView的大小
        let oldSize = textView.frame.size
        
        // 预设textView的大小,宽度设为固定宽度,高度设为CGFloat的最大值
        let presetSize = CGSize(width: textView.frame.size.width,height: CGFloat.greatestFiniteMagnitude)
        
        // 重新计算textView的实际大小
        let newSize = textView.sizeThatFits(presetSize)
        
        // 更新textView的大小
        textView.frame = CGRect(origin: CGPoint(x: textView.frame.origin.x,y: textView.frame.origin.y),size: CGSize(width: textView.frame.size.width,height: newSize.height))
        
        // 当高度变化时,刷新tableview(beginUpdates和endUpdates必须成对使用)
        if newSize.height != oldSize.height {
            self.tableView.beginUpdates()
            self.tableView.endUpdates()
        }
    }
    
}

实现效果:

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...