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