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 ...) ?