Supplementary Views not being deleted

2019-04-20 19:02发布

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?

1条回答
迷人小祖宗
2楼-- · 2019-04-20 19:59

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.

查看更多
登录 后发表回答