Reputation: 19592
I have a collectionView cell that has an isExpanded: Bool
property. When the cell first loads it is set to false
and it only shows 1 line of text. If the text is several lines long I append "more ..." to the end of the first line and if the label is pressed I expand the cell. It works but I have to press the label twice to expand the cell and then twice again to collapse the cell back to 1 line.
What I've come to find out is when I first press the label I check to see if isExpanded == false
and if it is I set it to true
then pass the cell's index.item back in a protocol and call performBatchUpdates
and then collectionView.reloadItems(at:)
.
After it runs I check isExpanded
and instead of it being true
it's false
so the cell doesn't expand. If I press the label again now everything works the way it supposed to and the isExpanded is true
and the cell expands.
Why do does the isExpanded
property get set to false
on the first go around even though I set it to true but on the second go around it stays set to true?
For a little more clarity
isExpanded
is initially false
isExpanded
gets set to true
performBatchUpdates
and reloadItems(at:)
runs isExpanded
somehow gets set back to false
(this is the problem)isExpanded
gets set to true
performBatchUpdates
and reloadItems(at:)
runs once again isExpanded
is true
(this is what should happen on the 3rd step).It should be a 3 step process but it's always a 5 step process.
When collapsing the cell the same thing happens and I have to press the label twice for it to collapse.
Cell Class
protocol: MyCellDelegate: class {
func expandOrCollapseCell(indexItem: Int)
}
weak var delegate: MyCellDelegate?
var indexItem: Int = 0
var isExpanded = false
var review: Review? {
didSet {
if let review = review else { return }
// run logic to expand or collapse cell depending on wether isExpanded is true or false
}
}
func tapGestureForLabel() {
if !isExpanded {
isExpanded = true
} else {
isExpanded = false
}
delegate?.expandOrCollapseCell(indexItem: self.indexItem)
}
And inside the class with the CollectionView
func expandOrCollapseCell(indexItem: Int) {
let indexPath = IndexPath(item: indexItem, section: 0)
UIView.animate(withDuration: 0) {
self.collectionView.performBatchUpdates({ [weak self] in
self?.collectionView.reloadItems(at: [indexPath])
self?.collectionView.layoutIfNeeded()
}) { (_) in
print("finished updating cell")
}
}
}
I tried passing isExpanded
in the protocol (I removed it) and inside the class with the CollectionView I updated the cell's isExpanded
property like this but it made no difference
func expandOrCollapseCell(indexItem: Int, isExpanded: Bool) {
if let cell = self.collectionView.cellForItem(at: indexPath) as? MyCell {
cell.isExpanded = isCellExpanded
}
// perform batchUpdates ...
}
Upvotes: 1
Views: 348
Reputation: 100503
This is a common problem of relying to the cell which is dequeued to hold a model state like
var isExpanded = false // should be inside model of each cell
you need to add this data to the model of the cell and check it when you need to change the state , then make the reload
Upvotes: 1