Reputation: 271
I have a collectionview with two sections, each sections have one item. The cell in section contains collectionview and I need to fit height cell to content collectionview.
My first section has a fixed height to 120 because it's horizontal collectionview and height not changed. But for second section number of elements can be changed and I need to display all items (collectionview have scrollEnabled to false and scrolldirecton to vertical).
My problem is I need to display a collectionview with two scrolldirection depends sections and display all items for vertical collectionview.
When I do collectionview.collectionViewLayout.collectionViewContentSize.height
I have the good height but I don't know how passed this height to parent viewcontroller. I search a dynamic solution to fixed this.
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
// MARK: - UICollectionViewDataSource
func numberOfSections(in collectionView: UICollectionView) -> Int {
return presenter.numberOfSections // == 2
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return presenter.numberOfItemsInSection // == 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueCell(InlineDisplayCollectionViewCell.self, for: indexPath)
configureCell(cell, at: indexPath)
return cell
}
// MARK: - UICollectionViewDelegateFlowLayout
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let type = presenter.typeAtIndexPath(indexPath)
switch type {
case .city:
return CGSize(width: collectionView.frame.width, height: 120)
case .suggestion:
return CGSize(width: collectionView.frame.width, height: 820)
default:
return CGSize.zero
}
}
}
class InlineDisplayCollectionViewCell: UICollectionViewCell, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
@IBOutlet weak var collectionView: UICollectionView!
var itemType: ItemModelCollectionType! = .city {
didSet {
updateCell()
}
}
var cities: [City]? {
didSet {
collectionView.reloadData()
}
}
var suggestions: [Suggestion]? {
didSet {
collectionView.reloadData()
}
}
override func awakeFromNib() {
super.awakeFromNib()
configureView()
}
// MARK: - UICollectionViewDataSource
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return itemType == .city ? cities?.count ?? 0 : suggestions?.count ?? 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell: UICollectionViewCell
if itemType == .city {
let cityCell = collectionView.dequeueCell(CityCollectionViewCell.self, for: indexPath)
configure(cell: cityCell, at: indexPath)
cell = cityCell
} else {
let suggestionCell = collectionView.dequeueCell(SquareCollectionViewCell.self, for: indexPath)
configure(cell: suggestionCell, at: indexPath)
cell = suggestionCell
}
return cell
}
// MARK: - UICollectionViewDelegateFlowLayout
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return itemType == .city ? 10 : 10
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return itemType == .city ? 0 : 10
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let size: CGSize
if itemType == .city {
size = CGSize(width: 100, height: 120)
} else {
let width = (collectionView.frame.width - (collectionView.contentInset.left + collectionView.contentInset.right) - 10) * 0.5
let height = width
size = CGSize(width: width, height: height)
}
return size
}
// MARK: - Private functions
private func configureView() {
collectionView.delegate = self
collectionView.dataSource = self
collectionView.contentInset = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)
collectionView.registerNib(CityCollectionViewCell.self, bundle: nil)
collectionView.registerNib(SquareCollectionViewCell.self, bundle: nil)
}
private func updateCell() {
if let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
flowLayout.scrollDirection = itemType == .city ? .horizontal : .vertical
}
collectionView.isScrollEnabled = itemType == .city
}
private func configure(cell: CityCollectionViewCell, at indexPath: IndexPath) {
guard let city = cities?[indexPath.row] else { return }
cell.configure(with: city)
}
private func configure(cell: SquareCollectionViewCell, at indexPath: IndexPath) {
guard let suggestion = suggestions?[indexPath.row] else { return }
cell.configure(with: suggestion)
}
}
Upvotes: 1
Views: 533
Reputation: 19
Unfortunately you can't do something like that. But you can have different types of cells inside your CV. Also you can modify that in the function called "cellForItemAt".
Upvotes: 0
Reputation: 416
You can't do that. CollectionView cells are dequeued and reused dynamically. The best way to go about it is to use different types of cells within the same CollectionView.
Please check the questions I have posted on this topic: Get the sum of all collectionViewCells' heights inside a CollectionView and Multiple Cells for Comments and Reply in a CollectionView
Upvotes: 0