UICollectionView bên trong một UITableViewCell - Dynamic height

Bài viết này mình sẽ hướng dẫn các bạn cách làm một UICollectionView bên trong một UITableViewCell. UICollectionView có số items là dynamic, height của UITableViewCell cũng sẽ được dynamic dựa theo height của UICollectionView.

Mình tạo view như sau:

Bên trong tableviewcell là một uicollectionview. UIcollectionViewCell là 1 Label. Mình autolayout cho UICollectionView cách top, left, right, bottom là 0 so với supperview.

Đoạn code ở ViewController như sau:

Mình giải thích một chút: tableview mình có 1 cell, mình mong muốn hiển thị mảng items gồm 15 phần tử như trong ảnh. Vì mình muốn chiều cao của tableviewcell là linh động theo chiều cao của uicollectionview nên mình đặt heightForRowAtIndexPath = UITableView.automaticDimension.

Bây giờ là đoạn code ở file TableViewCell:

Bên trong tableviewcell có một uicollectionview.

Bây giờ mình build ứng dụng lên thử nhé, đây là kết quả:

Nó không giống như mình mong đợi, nó chỉ hiển thị được 4 phần tử bên trong uitablewcell mặc dù mình đã dùng UITableView.automaticDimension.

Giải pháp ở đây là tính toán collectionViewContentSize và gán lại cho contentSize của UITablewViewCell. Phương pháp này gọi là "does the magic": Thêm đoạn code sau vào file TableViewCell:

override func systemLayoutSizeFitting(_ targetSize: CGSize, withHorizontalFittingPriority horizontalFittingPriority: UILayoutPriority, verticalFittingPriority: UILayoutPriority) -> CGSize {
        self.collectionView.layoutIfNeeded()
        self.layoutIfNeeded()
        let contentSize = self.collectionView.collectionViewLayout.collectionViewContentSize
        return CGSize(width: contentSize.width, height: contentSize.height + 8)
    }

File TablewViewCell hiện tại sẽ thế này:

Rồi, bây giờ mình run kết quả nhé:

Bây giờ nó đã giống như mình mong đợi 😃. Mình thay đổi mảng items xem nó sẽ hiển thị thế nào nhé:

items = ["label 1", "label 2", "label 3", "label 4", "label 5", "label 6", "label 7", "label 8", "label 9", "label 10", "label 11", "label 12", "label 13", "label 14", "label 15", "hihi 1", "hihi 1","hihi 2","hihi 3","hihi 4","hihi 5","hihi 6","hihi 7","hihi 8","hihi 9","hihi 10"]

Nó hiển thị rất tốt như mình mong đợi rồi:

Cảm ơn các bạn đã xem bài viết. Happy coding 😃