Reputation: 1251
I am trying to dynamically adjust cells in a CollectionView according to the contents of a label. Basically i have found how to but my challenge is
cellForItemAt method
gets called first before
heightForCellAtIndexPath method
and by doing so this means we are trying to get heights before data is loaded so the cells will always be the same height and therefore we wont achieve different heighted cells
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let content_ = content[indexPath.row]
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "NotesUI", for: indexPath) as! NotesUI
cell.setData(data: content_)
return cell
}
func collectionView(_ collectionView: UICollectionView, heightForCellAtIndexPath indexPath:IndexPath) -> CGFloat {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "NotesUI", for: indexPath) as! NotesUI
return cell.allNoteViews()[indexPath.item - 1].bounds.size.height
}
Essentially in the NotesUI CollectionView class:
class NotesUI:UICollectionViewCell{
@IBOutlet var note: UILabel!
var views: [UILabel] = []
func setData(data: NoteModel){
note.text = data.note
note.numberOfLines = 0
note.lineBreakMode = NSLineBreakMode.byWordWrapping
note.sizeToFit()
views.append(note)
}
func allNoteViews()->[UILabel]{
return views
}
}
I guess my question boils down to how can i call heightForCellAtIndexPath method after the cellForItemAt method so that the CollectionView gets the height of the label after it has contents
Upvotes: 1
Views: 208
Reputation: 2335
You don't need to calculate each cell height if you use auto layout. You can add a vertical stack view to your cell and add your labels to it.
Here is a basic example of self-sizing collection view cells.
class YourCustomCell: UICollectionViewCell {
// Add your labels to this stackView
@IBOutlet weak var yourLabelContainer: UIStackView!
override func awakeFromNib() {
super.awakeFromNib()
yourLabelContainer.translatesAutoresizingMaskIntoConstraints = false
yourLabelContainer.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.size.width - 32).isActive = true // for 16 - 16 padding
}
}
class YourViewController: UIViewController {
@IBOutlet weak var yourCollectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
yourCollectionView.delegate = self
yourCollectionView.dataSource = self
let nib = UINib(nibName: "YourCustomCell", bundle: nil)
yourCollectionView.register(nib, forCellWithReuseIdentifier: "cellReuseId")
if let layout = yourCollectionView.collectionViewLayout as? UICollectionViewFlowLayout {
layout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
}
}
}
Upvotes: 1