Updated 26 October 2021
In Most of time we use the collection view inside the table view cell if the collection view flow is vertical then we need to increase the height of table view cell or if flow layout is horizontal then we fix some constant height for table view cell .
Here I am discussing about how to manage the table view cell height automatically if collection view flow layout is vertical
Follow the Steps:
1: Go to Table view Cell class & create the outlet of collection view & collection view Height Constraints.
1 2 3 4 5 |
class ProductTableViewCell: UITableViewCell { @IBOutlet weak var prodcutCollectionView: UICollectionView! @IBOutlet weak var productCollectionViewHeight: NSLayoutConstraint! } |
2: Now Register the Collection view cell so we can use .
1 2 3 4 5 6 7 8 9 10 11 |
override func awakeFromNib() { super.awakeFromNib() productCollectionViewHeight.constant = 20 prodcutCollectionView.register(UINib(nibName: "ProductImageCell", bundle: nil), forCellWithReuseIdentifier: "productimagecell") prodcutCollectionView.delegate = self prodcutCollectionView.dataSource = self } |
3: Now write their All delegate & data source method inside the table view cell class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
extension ProductTableViewCell: UICollectionViewDelegate, UICollectionViewDataSource , UICollectionViewDelegateFlowLayout{ func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return productCollectionModel.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "productimagecell", for: indexPath) as! ProductImageCell cell.layer.cornerRadius = 8 NetworkManager.sharedInstance.getImageFromUrl(imageUrl:productCollectionModel[indexPath.row].bannerImage , imageView: cell.productImage) cell.productName.text = productCollectionModel[indexPath.row].name cell.productPrice.text = productCollectionModel[indexPath.row].price headerTitle.text = titles return cell } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return CGSize(width: collectionView.frame.size.width/2 - 16 , height: collectionView.frame.size.width/2 + 70) } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { delegate.productClick(name: productCollectionModel[indexPath.row].name, image: productCollectionModel[indexPath.row].bannerImage, id: productCollectionModel[indexPath.row].Id) } } |
4: Now the Collection View delegate & data source are set , now move to Table View Delegate & Data source.
5: Now register the tableview cell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class ViewController: UIViewController ,featureViewControllerHandlerDelegate,bannerViewControllerHandlerDelegate,productViewControllerHandlerDelegate,UITabBarControllerDelegate{ @IBOutlet weak var homeTableView: UITableView! override func viewDidLoad() { super.viewDidLoad() homeTableView?.register(ProductTableViewCell.nib, forCellReuseIdentifier: ProductTableViewCell.identifier) self.homeTableView?.dataSource = self; self.homeTableView?.delegate = self homeTableView.rowHeight = UITableViewAutomaticDimension self.homeTableView.estimatedRowHeight = 100 self.homeTableView.separatorColor = UIColor.clear } |
6: After register the Tableview Cell & we have to define their delegate & Data source.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
extension viewController : UITableViewDelegate , UITableViewDataSource { public func numberOfSections(in tableView: UITableView) -> Int{ return 1; } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{ return 1 } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return UITableViewAutomaticDimension } } |
7: Now its Time to return the cell , here i am creating the vertical flow of collection view where the collection view height is fixed, so its automatically increase the table view cell size.
1 2 3 4 5 6 7 8 9 10 |
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell:ProductTableViewCell = tableView.dequeueReusableCell(withIdentifier: ProductTableViewCell.identifier) as! ProductTableViewCell cell.productCollectionModel = ((item as? HomeViewModelProductItem)?.productCollectionModel)! cell.frame = tableView.bounds cell.layoutIfNeeded() cell.prodcutCollectionView.reloadData() cell.productCollectionViewHeight.constant = cell.prodcutCollectionView.collectionViewLayout.collectionViewContentSize.height return cell; } |
8 Notes : these are the important part to automate your table view cell
cell.frame = tableView.bounds
cell.layoutIfNeeded()
cell.prodcutCollectionView.reloadData()
cell.productCollectionViewHeight.constant = cell.prodcutCollectionView.collectionViewLayout.collectionViewContentSize.height
9: Now your Table View Cell automatically increase without calculating the height of each collection view.
If you have more details or questions, you can reply to the received confirmation email.
Back to Home
8 comments
the first cell resize and get to long like the same size of the cell underneath it
Just replace the code where you reload the table view by this extension .
yourTableviewRefrence.reloadDataWithAutoSizingCellWorkAround()
extension UITableView {
func reloadDataWithAutoSizingCellWorkAround() {
self.reloadData()
self.setNeedsLayout()
self.layoutIfNeeded()
self.reloadData()
}
}
lag occurred because of reloading collection view and adding collection view height