Receiving notification on a UICollectionViewCell's (or UITableViewCell's) removal from its parent collection or table view
-
21-07-2021 - |
Question
Background:
I have a UICollectionViewController
that shows items in one of two modes, which the user can toggle between. Each mode uses a different class of UICollectionViewCell
. Let's call these modes "list view" and "grid view".
When I switch modes, I call .reloadData
on the UICollectionView
, which redraws the collection view using the correct cell classes. Everything works fine here.
Now: Inside the UICollectionViewCell
subclass for one type of cells, I want to be notified when the collection view that contains it switches modes. Visually, a cell which was on-screen vanishes; the collection view is drawn fully with the other type of cell. When switching back, the cell is re-displayed.
Question:
How can I be notified when a UICollectionViewCell
is "removed" (i.e., no longer shown; I'm not sure what's happening under the hood yet) from its parent collection view?
Notes:
prepareForReuse
is not called on the cell when the collection view'supdateData
causes the cell to no longer be included.willTransitionFromLayout:toLayout:
(an empty layout?) is not called.- Overriding
didMoveToSuperview
is of no help; it is not called. - Observing
.hidden
or.alpha
on the cell does not work. - The cell's
dealloc
is not called; it sticks around in the reuse queue.
Something in the cell must be changing that I can observe or hook into, what is it?
Solution
Update: UICollectionViewDelegate
has this method, which from the documentation seems like it does what I am asking:
- collectionView:didEndDisplayingCell:forItemAtIndexPath:
Original answer:
I got this working as desired by having the UICollectionViewController
manually notify visible cells of impending doom with this method when I'm about to toggle and call reloadData
:
- (void)notifyCellsWillBeHidden {
for (UICollectionViewCell *cell in self.collectionView.visibleCells) {
if ([cell respondsToSelector:@selector(willBeRemovedFromCollectionView)]) {
[cell performSelector:@selector(willBeRemovedFromCollectionView)];
}
}
}
These cells can then do what they need to do if they implement the above method.
Calling prepareForReuse
may not a good idea because it will be called again before the cells are re-displayed, if this is a problem.
I'm still curious whether there is a way for a cell to receive notification that it is going to be made non-visible without an explicit call.