I am building a custom layout collection view. I have 2 Supplementary Views per item in my collection. And when I want to delete an item, my layoutAttributesForSupplementaryViewOfKind:atIndexPath:
implementation is called with Supplementary Views that should no longer exist. This means I'm getting an index path which doesn't map to my data source properly and I get an out of bounds problem.
I did some logging and what follows in the first instance is the correct and logical way the collection view is computed when we begin with some data, or whenever we insert an item into the collection view.
The second set of logs is when I deleteItemsAtIndexPaths:
after deleting an object from my data source.
My layoutAttributesForElementsInRect:
looks like this:
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSMutableArray* attributes = [NSMutableArray array];
for (NSInteger i = 0 ; i < [self.myData count]; i++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
NSLog(@"%@ indexPath.row:%d", NSStringFromSelector(_cmd), indexPath.row);
UICollectionViewLayoutAttributes *att = [self layoutAttributesForItemAtIndexPath:indexPath];
[attributes addObject:att];
UICollectionViewLayoutAttributes *att_supp = [self layoutAttributesForSupplementaryViewOfKind:@"one_kind" atIndexPath:indexPath];
[attributes addObject:att_supp];
UICollectionViewLayoutAttributes *linesAttr = [self layoutAttributesForSupplementaryViewOfKind:@"another_kind" atIndexPath:indexPath];
[attributes addObject:linesAttr];
}
return attributes;
}
Initial logs (correct and logical):
MyApp[18546:70b] layoutAttributesForElementsInRect: indexPath.row:0
MyApp[18546:70b] layoutAttributesForSupplementaryViewOfKind:atIndexPath: indexPath.row:0
MyApp[18546:70b] layoutAttributesForSupplementaryViewOfKind:atIndexPath: indexPath.row:0
MyApp[18546:70b] layoutAttributesForElementsInRect: indexPath.row:1
MyApp[18546:70b] layoutAttributesForSupplementaryViewOfKind:atIndexPath: indexPath.row:1
MyApp[18546:70b] layoutAttributesForSupplementaryViewOfKind:atIndexPath: indexPath.row:1
MyApp[18546:70b] layoutAttributesForElementsInRect: indexPath.row:2
MyApp[18546:70b] layoutAttributesForSupplementaryViewOfKind:atIndexPath: indexPath.row:2
MyApp[18546:70b] layoutAttributesForSupplementaryViewOfKind:atIndexPath: indexPath.row:2
After deleting an item:
MyApp[18633:70b] layoutAttributesForElementsInRect: indexPath.row:0
MyApp[18633:70b] layoutAttributesForSupplementaryViewOfKind:atIndexPath: indexPath.row:0
MyApp[18633:70b] layoutAttributesForSupplementaryViewOfKind:atIndexPath: indexPath.row:0
MyApp[18633:70b] layoutAttributesForElementsInRect: indexPath.row:1
MyApp[18633:70b] layoutAttributesForSupplementaryViewOfKind:atIndexPath: indexPath.row:1
MyApp[18633:70b] layoutAttributesForSupplementaryViewOfKind:atIndexPath: indexPath.row:1
MyApp[18633:70b] layoutAttributesForSupplementaryViewOfKind:atIndexPath: indexPath.row:2
As you can see layoutAttributesForSupplementaryViewOfKind:atIndexPath:
is called but by bypassing layoutAttributesForElementsInRect:
Does anyone know what might be going wrong?
I had this same issue. My layout uses one supplementary view for every item in the collection view. I solved it with a couple of steps.
First, in - prepareForCollectionViewUpdates:
, I enumerate over the updates and determine which items are disappearing. I cache that set of index paths.
The layout will then call - indexPathsToDeleteForSupplementaryViewOfKind:
. I just returned the cached result from above.
Finally, in - finalizeCollectionViewUpdates
, I clear the cache. I suppose this step is optional.
I also did this for - indexPathsToInsertForSupplementaryViewOfKind:
for consistency sake, although it worked just fine without it.
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