Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Supplementary Views not being deleted

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?

like image 838
Daniel Avatar asked Nov 14 '13 11:11

Daniel


1 Answers

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.

like image 65
calebd Avatar answered Oct 22 '22 00:10

calebd