UICollectionView Assertion failure

前端 未结 14 2213
别那么骄傲
别那么骄傲 2020-11-29 17:27

I m getting this error on performing insertItemsAtIndexPaths in UICollectionView

Assertion failure in:

-[UICollectionViewD         


        
14条回答
  •  星月不相逢
    2020-11-29 18:30

    I've posted a work around for this issue here: https://gist.github.com/iwasrobbed/5528897

    In the private category at the top of your .m file:

    @interface MyViewController ()
    {
        BOOL shouldReloadCollectionView;
        NSBlockOperation *blockOperation;
    }
    @end
    

    Then your delegate callbacks would be:

    - (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
    {
        shouldReloadCollectionView = NO;
        blockOperation = [NSBlockOperation new];
    }
    
    - (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id)sectionInfo
               atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
    {
        __weak UICollectionView *collectionView = self.collectionView;
        switch (type) {
            case NSFetchedResultsChangeInsert: {
                [blockOperation addExecutionBlock:^{
                    [collectionView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]];
                }];
                break;
            }
    
            case NSFetchedResultsChangeDelete: {
                [blockOperation addExecutionBlock:^{
                    [collectionView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]];
                }];
                break;
            }
    
            case NSFetchedResultsChangeUpdate: {
                [blockOperation addExecutionBlock:^{
                    [collectionView reloadSections:[NSIndexSet indexSetWithIndex:sectionIndex]];
                }];
                break;
            }
    
            default:
                break;
        }
    }
    
    - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
    {
        __weak UICollectionView *collectionView = self.collectionView;
        switch (type) {
            case NSFetchedResultsChangeInsert: {
                if ([self.collectionView numberOfSections] > 0) {
                    if ([self.collectionView numberOfItemsInSection:indexPath.section] == 0) {
                        shouldReloadCollectionView = YES;
                    } else {
                        [blockOperation addExecutionBlock:^{
                            [collectionView insertItemsAtIndexPaths:@[newIndexPath]];
                        }];
                    }
                } else {
                    shouldReloadCollectionView = YES;
                }
                break;
            }
    
            case NSFetchedResultsChangeDelete: {
                if ([self.collectionView numberOfItemsInSection:indexPath.section] == 1) {
                    shouldReloadCollectionView = YES;
                } else {
                    [blockOperation addExecutionBlock:^{
                        [collectionView deleteItemsAtIndexPaths:@[indexPath]];
                    }];
                }
                break;
            }
    
            case NSFetchedResultsChangeUpdate: {
                [blockOperation addExecutionBlock:^{
                    [collectionView reloadItemsAtIndexPaths:@[indexPath]];
                }];
                break;
            }
    
            case NSFetchedResultsChangeMove: {
                [blockOperation addExecutionBlock:^{
                    [collectionView moveItemAtIndexPath:indexPath toIndexPath:newIndexPath];
                }];
                break;
            }
    
            default:
                break;
        }
    }
    
    - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
    {
        // Checks if we should reload the collection view to fix a bug @ http://openradar.appspot.com/12954582
        if (shouldReloadCollectionView) {
            [self.collectionView reloadData];
        } else {
            [self.collectionView performBatchUpdates:^{
                [blockOperation start];
            } completion:nil];
        }
    }
    

    Credit for this approach goes to Blake Watters.

提交回复
热议问题