I'm developing an app which requires me to have two types of feed inside my ViewController - Horizontal and Vertical.
The structure is like this: ViewController -> UITableView
-> first section has horizontal UICollectionView
-> second section has vertical UICollectionView
.
My issue is that i'm unable to get the second section of the UITableView
(which has inside the Vertical UICollectionView
) to have a proper height. It gets interrupted in the middle when I'm scrolling down.
It's important to say that the UICollectionView cell height is not fixed.
I followed some tutorials and guides out there and saw many use cases of UITableViewAutomaticDimension
, but couldn't get it to work.
Edit: Here is how my storyboard looks like: My StoryBoard This is my main ViewController code:
class FeedViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { @IBOutlet weak var tableView: UITableView! var stationArray = Array() override func viewDidLoad() { super.viewDidLoad()d } func numberOfSections(in tableView: UITableView) -> Int { return 2 } func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { return categories[section] } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 1 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { if indexPath.section == 0 { let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! FeedHorizontalTableViewCell *Some code* return cell } else { let cell2 = tableView.dequeueReusableCell(withIdentifier: "cell2") as! FeedVerticalTableViewCell *Some code* cell2.setNeedsLayout() return cell2 } } func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { if section == 1 { return 50 } return 0 } func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { return 500 } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { if indexPath.section == 0 { if let cell = tableView.dequeueReusableCell(withIdentifier: "cell") { return cell.frame.height } return 280 } else { return UITableViewAutomaticDimension } } }
This is my vertical UITableViewCell code:
class FeedVerticalTableViewCell: UITableViewCell, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { @IBOutlet weak var collectionView: UICollectionView! var stations = Array() { didSet { collectionView.reloadData() } } override func awakeFromNib() { super.awakeFromNib() } override func setSelected(_ selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return stations.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "feedVerticalCell", for: indexPath) as! FeedVerticalCollectionViewCell *some code* return cell } }
After setting UITableView cell height to be dynamic in you view controller.
tableView.estimatedRowHeight = 100
tableView.rowHeight = UITableViewAutomaticDimension
Create a subclass for your vertical collectionView and override intrinsicContentSize.
class DynamicCollectionView: UICollectionView {
override func layoutSubviews() {
super.layoutSubviews()
if !__CGSizeEqualToSize(bounds.size, self.intrinsicContentSize) {
self.invalidateIntrinsicContentSize()
}
}
override var intrinsicContentSize: CGSize {
return collectionViewLayout.collectionViewContentSize
}
}
In Interface builder change the class of your collectionView to DynamicCollectionView (subclass UICollectionView).
Set estimated cell size of UICollectionViewFlowLayout.
flowLayout.estimatedItemSize = CGSize(width: 1,height: 1)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With