Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> iOS

Thay đổi chiều cao TableView Cell động (Dynamic Height) trong Swift

Để UITableViewCell tự điều chỉnh chiều cao theo nội dung (dynamic height), dùng UITableView.automaticDimension kết hợp estimatedRowHeight.

Setup TableView


func setupTableView() {
    let tableView = UITableView(frame: view.bounds, style: .plain)
    tableView.dataSource = self
    tableView.delegate = self
    tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
    tableView.backgroundColor = .systemGroupedBackground
    
    // KEY: Bật automatic dimension
    tableView.estimatedRowHeight = 100  // Ước lượng height (giúp scroll indicator mượt)
    tableView.rowHeight = UITableView.automaticDimension
    
    view.addSubview(tableView)
}

DataSource


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 5 }

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
    
    // QUAN TRỌNG: Cell mặc định có textLabel.numberOfLines = 1
    // Phải set = 0 để multiline
    cell.textLabel?.numberOfLines = 0
    cell.textLabel?.font = .systemFont(ofSize: 16)
    
    // Nội dung khác nhau cho từng row
    if indexPath.row == 1 {
        cell.textLabel?.text = "Dòng ngắn"
    } else if indexPath.row == 2 {
        cell.textLabel?.text = "Dòng rất dài sẽ tự động xuống hàng nhiều lần để hiển thị toàn bộ nội dung này trong cell mà không bị cắt ngắn hay truncate."
    } else {
        cell.textLabel?.text = "Row \(indexPath.row)"
    }
    
    return cell
}

KHÔNG implement heightForRowAt

Khi dùng automaticDimension, KHÔNG implement heightForRowAt (hoặc return UITableView.automaticDimension).

Kết quả

Row 2 (dòng dài) tự cao hơn các row khác:

Thay đổi chiều cao TableView Cell động (Dynamic Height) trong Swift

Yêu cầu bắt buộc cho Auto Layout trong Cell

  • Cell content view có constraints từ top đến bottom (vertical chain).
  • Nếu dùng custom cell xib/storyboard: Các subview phải pinned top/bottom tới contentView.
  • Label: numberOfLines = 0, có constraint top/bottom/leading/trailing.
  • ImageView: Cần aspect ratio constraint hoặc fixed height.

Custom Cell với Auto Layout (Xib/Storyboard)


class CustomCell: UITableViewCell {
    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var bodyLabel: UILabel!
    
    override func awakeFromNib() {
        super.awakeFromNib()
        titleLabel.numberOfLines = 0
        bodyLabel.numberOfLines = 0
    }
}

Lưu ý

  • estimatedRowHeight giúp scroll bar mượt – set giá trị trung bình mong đợi.
  • iOS 11+: rowHeight = UITableView.automaticDimension là default, nhưng set explicit cho rõ ràng.
  • Performance: Automatic dimension tính toán layout mỗi cell – với hàng nghìn row phức tạp, cân nhắc cache height hoặc fixed height.
  • Self-sizing cells cũng áp dụng cho UICollectionView (estimatedItemSize).