UICollectionView Assertion failure

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

I m getting this error on performing insertItemsAtIndexPaths in UICollectionView

Assertion failure in:

-[UICollectionViewD         


        
相关标签:
14条回答
  • 2020-11-29 18:03

    Just for the record, I ran into the same problem and for me the solution was to remove the header (disable them in the .xib) and as them were not needed anymore removed this method. After that everything seems fine.

    - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementary
    ElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
    
    0 讨论(0)
  • 2020-11-29 18:04

    Here is a non-hack, docs-based answer to the problem. In my case, there was a condition according to which I would return a valid or a nil supplementary view from collectionView:viewForSupplementaryElementOfKind:atIndexPath:. After encountering the crash, I checked the docs and here is what they say:

    This method must always return a valid view object. If you do not want a supplementary view in a particular case, your layout object should not create the attributes for that view. Alternatively, you can hide views by setting the hidden property of the corresponding attributes to YES or set the alpha property of the attributes to 0. To hide header and footer views in a flow layout, you can also set the width and height of those views to 0.

    There are other ways to do this, but the quickest seems to be:

    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewFlowLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section {
        return <condition> ? collectionViewLayout.headerReferenceSize : CGSizeZero;
    }
    
    0 讨论(0)
  • 2020-11-29 18:09

    I ran into this very same problem when inserting the first cell into a collection view. I fixed the problem by changing my code so that I call the UICollectionView

    - (void)reloadData
    

    method when inserting the first cell, but

    - (void)insertItemsAtIndexPaths:(NSArray *)indexPaths
    

    when inserting all other cells.

    Interestingly, I also had a problem with

    - (void)deleteItemsAtIndexPaths:(NSArray *)indexPaths
    

    when deleting the last cell. I did the same thing as before: just call reloadData when deleting the last cell.

    0 讨论(0)
  • 2020-11-29 18:12

    It seems that the problem occurs when you either insert or move a cell to a section that contains a supplementary header or footer view (with UICollectionViewFlowLayout or a layout derived from that) and the section has a count of 0 cells before the insertion / move.

    I could only circumvent the crash and still maintain the animations by having an empty and invisible cell in the section containing the supplementary header view like this:

    1. Make - (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section return the actual cell `count + 1 for that section where the header view is.
    2. In - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath return

      if ((indexPath.section == YOUR_SECTION_WITH_THE_HEADER_VIEW) && (indexPath.item == [self collectionView:collectionView numberOfItemsInSection:indexPath.section] - 1)) {
              cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"EmptyCell" forIndexPath:indexPath];
      }
      

      ... an empty cell for that position. Remember to register the cell reuse in viewDidLoad or wherever you initialize your UICollectionView:

      [self.collectionView registerClass:[UICollectionReusableView class] forCellWithReuseIdentifier:@"EmptyCell"];
      
    3. Use moveItemAtIndexPath: or insertItemsAtIndexPaths: without crashing.
    0 讨论(0)
  • 2020-11-29 18:13

    Check that you are returning the correct number of elements in the UICollectionViewDataSource methods:

    - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
    

    and

    - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
    
    0 讨论(0)
  • 2020-11-29 18:15

    Inserting section#0 just before inserting cells seems make UICollectionView happy.

    NSArray *indexPaths = /* indexPaths of the cells to be inserted */
    NSUInteger countBeforeInsert = _cells.count;
    dispatch_block_t updates = ^{
        if (countBeforeInsert < 1) {
            [self.collectionView insertSections:[NSIndexSet indexSetWithIndex:0]];
        }
        [self.collectionView insertItemsAtIndexPaths:indexPaths];
    };
    [self.collectionView performBatchUpdates:updates completion:nil];
    
    0 讨论(0)
提交回复
热议问题