Swift: expand the height of the UITableViewCell based on the size of the UICollectionView inside

Hello to all. I started learning programming 1 month ago, so please be kind if I don't explain my problem well :)

My project consists of a basic UITableView . In each UITableView cell, I have a UICollectionView (when scrolling horizontally).

Img 1: Main view

the width of each UICollectionViewCell same as the whole UITableViewCell . My first problem is determining the size of the UITableViewCell (which will depend on the size of the UICollectionView itself and the size of the content on top of it).

Img 2: CollectionView

This must be done automatically. In fact, the UICollectionViewCell will not have the same height , so when the user scrolls the UICollectionView horizontally, a new UICollectionViewCell (with different heights) will appear and the height of the UITableViewCell will have to be adapted.

The second problem is determining the size of the UICollectionViewCell , in fact I will not know in advance what its height will be (the width is the same as that of the UITableView ). I have to import the content from the bottom.

So here is my ViewController file,

variables:

 @IBOutlet weak var tableView: UITableView! var storedOffsets = [Int: CGFloat]() 

UITableView extension: create a UITableView cell and set the UICollectionView delegate inside it

 extension IndexVC: UITableViewDelegate, UITableViewDataSource { func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 6 //Temp } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { if let cell = tableView.dequeueReusableCellWithIdentifier("CellCollectionView") as? CellPost { let post = self.posts[indexPath.row] cell.configureCell(post) return cell } else { return CellPost() } } func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { guard let tableViewCell = cell as? CellPost else { return } tableViewCell.setCollectionViewDataSourceDelegate(self, forRow: indexPath.row) tableViewCell.collectionViewOffset = storedOffsets[indexPath.row] ?? 0 } func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { guard let tableViewCell = cell as? CellPost else { return } storedOffsets[indexPath.row] = tableViewCell.collectionViewOffset } 

UICollectionView part: add a view from Nib / xib to the cell

 extension IndexVC: UICollectionViewDelegate, UICollectionViewDataSource { func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 9 //Temp } func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cellInCollectionView", forIndexPath: indexPath) if let textPostView = NSBundle.mainBundle().loadNibNamed("textPostView", owner: self, options: nil).first as? textPostView { textPostView.configurePost(post.descriptionLbl) cell.addSubview(textPostView) textPostView.translatesAutoresizingMaskIntoConstraints = false cell.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[view]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["view":textPostView])) cell.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[view]", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["view":textPostView])) } return cell } 

Make the cell size the same as the whole UICollectionView

 extension IndexVC: UICollectionViewDelegateFlowLayout { func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { return CGSizeMake(collectionView.frame.width, collectionView.frame.height) } 

And I created this extension in a class designed for UITableViewCell (not useful for the problem, but if any of you want to recreate it)

 extension CellPost { func setCollectionViewDataSourceDelegate<D: protocol<UICollectionViewDataSource, UICollectionViewDelegate>>(dataSourceDelegate: D, forRow row: Int) { collectionView.delegate = dataSourceDelegate collectionView.dataSource = dataSourceDelegate collectionView.tag = row collectionView.setContentOffset(collectionView.contentOffset, animated:false) // Stops collection view if it was scrolling. collectionView.reloadData() } var collectionViewOffset: CGFloat { set { collectionView.contentOffset.x = newValue } get { return collectionView.contentOffset.x } } 

If someone wants to use this code, it works fine, but I need to hardcode the height of the UITableView with tableView( ... heightForRowAtIndexPath ...)

I tried everything so that the UITableViewCell adapts to what is inside (I tried to calculate the size of the content sent by Nib, which I put in the cell and then send it to tableView( ... heightForRowAtIndexPath ...) but I can't get it to work "I also tried car dealers, but maybe I am doing it wrong. I also think that the problem may come from the part that I imported in my cell.

I also have no idea how to expand the cell after the user UICollectionViewCell , is there a way to create an event when this happens? And maybe call tableView( ... heightForRowAtIndexPath ...) again tableView( ... heightForRowAtIndexPath ...) ?

+5
ios uitableview swift uicollectionview cell
Jul 21 '16 at 3:03
source share
2 answers

As I understand it, you need to automatically adjust the height of the table cell. so you can use autostart to adjust cell height.

Record in ViewDidLoad

 self.tableView.estimatedRowHeight = 80 self.tableView.rowHeight = UITableViewAutomaticDimension 

Before returning a cell to CellForRowAtIndexPath

 self.tableView.setNeedsLayout() self.tableView.layoutIfNeeded() 

You can find the link for autorun. enter the link here

+1
Jul 21 '16 at 7:21
source share

To solve my problem, I created an array to store the height of each cell of the UITableView (named cellHeight ).

I also calculate the height of each cell at the beginning of the program in an array consisting of an array (named cellHeightForPost ). The main array represents all the TableView cells , each array inside it represents the height of each "collectionView" cell

To update the table view every time I change the collectionView inside it, I used fonction collectionView(... willDiplayCell...) :

 self.tableView.beginUpdates() cellHeight[collectionView.tag] = cellHeightForPost[collectionView.tag][indexPath.row] self.tableView.setNeedsLayout() self.tableView.layoutIfNeeded() self.tableView.endUpdates() 

My UITableView size is defined in tableView(... heightForRowAtIndexPath) and tableView(... estimatedHeightForRowAtIndexPath) :

 return cellHeight[indexPath.row] 

To set the size of collectionViewCells :

 return CGSize(width: collectionView.frame.width, height: cellHeightForPost[collectionView.tag][indexPath.row]) 
0
Jul 24. '16 at 4:19
source share



All Articles