21

UICollectionViewData validateLayoutInRectiOS7中的断言失败。

我正在尝试使用循环UICollectionView一一删除所有项目;for我在下面发布了我的代码。我使用删除UICollectionView项目deleteItemsAtIndexPaths。它在 iOS6 上完美运行,但在 iOS7 中崩溃,但有以下异常:

UICollectionViewData validateLayoutInRect 中的断言失败

collectionArray从那时起self.collectionView,我使用 . 一个一个地删除对象indexPath。当我删除第 4 个对象时,它会Assertion failure在 iOS7 上引发。我在这里使用performBatchUpdates.

请帮助我在 iOS7 中获得正确的结果。分享正确的代码。提前致谢。

try  {    
    for (int i=count-1; i>=0; i--)  {  
        [self.collectionView performBatchUpdates:^(void){  
            [collectionArray removeObjectAtIndex:i]; // First delete the item from you model   
            [self.collectionView deleteItemsAtIndexPaths:@[[NSIndexPath indexPathForRow:i inSection:0]]];  
        } completion:nil];
        [self.collectionView reloadData];
    }
}
@catch (NSException *exception) {
}
@finally {
}
4

8 回答 8

24

实际上,我有一次崩溃不是因为我为一个部分中的多个部分或项目返回零,而是因为我对多个集合视图重用了这样的流布局:

UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
Collection1 = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 50.0f) collectionViewLayout:flowLayout];
[Collection1 setDataSource:self];
[Collection1 setDelegate:self];
[self.view addSubview:Collection1];

Collection2 = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, self.view.frame.size.height) collectionViewLayout:flowLayout];
Collection2.backgroundColor = [UIColor whiteColor];

相反,如果我为每个 UICollectionView 创建一个新的流布局,我可以避免这种崩溃。希望这可以帮助某人

UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
Collection1 = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 50.0f) collectionViewLayout:flowLayout];
[Collection1 setDataSource:self];
[Collection1 setDelegate:self];
[self.view Collection1];

UICollectionViewFlowLayout *flowLayoutVert = [[UICollectionViewFlowLayout alloc] init];
[flowLayoutVert setScrollDirection:UICollectionViewScrollDirectionVertical];
Collection2 = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, self.view.frame.size.height) collectionViewLayout:flowLayoutVert];
于 2014-04-25T15:30:00.050 回答
20

在 iOS 10 中,您必须禁用 prefetchingEnabled:

// Swift
if #available(iOS 10, *) { 
    collectionView.prefetchingEnabled = false 
}

//Obj C
if ([self.collectionView respondsToSelector:@selector(setPrefetchingEnabled:)]) {
    self.collectionView.prefetchingEnabled = false;
}
于 2017-01-28T20:55:08.597 回答
4

看起来您可能想要这样做:

[self.CollectionView performBatchUpdates:^(void) {
  for (int i = count - 1; i >= 0; i--) {
    [collectionArray removeObjectAtIndex:i]; // First delete the item from you model
    [self.CollectionView deleteItemsAtIndexPaths:@[[NSIndexPath indexPathForRow:i inSection:0]]];
  }
} completion:nil];

这样所有的更新都是一起执行的。否则,您最终将尝试在彼此之上执行多个批量更新。

于 2014-08-06T08:51:53.307 回答
4

布局生命周期

您应该在您的配置中实现invalidateLayoutlayoutClass删除所有类型的UICollectionViewLayoutAttributes项目。

- (void)invalidateLayout{
  [super invalidateLayout];
  [self.itemsAttributes removeAllObjects];
}
于 2018-01-22T07:48:02.670 回答
2

您应该在布局类中实现 invalidateLayout 并删除配置中的各种UICollectionViewLayoutAttributes项目。

- (void)invalidateLayout{
  [super invalidateLayout];
  [self.itemsAttributes removeAllObjects];
}

如需更好的实现方式invalidateLayoutWithContext,请参阅更多关于 UICollectionViewLayoutInvalidationContext.

来自Apple 开发者文档

在实现自定义布局时,您可以覆盖此方法并使用它来处理自定义失效上下文提供的信息。您不需要提供自定义失效上下文,但如果您能够提供有助于优化布局更新的其他属性,则可以这样做。如果你重写了这个方法,你必须在你的实现中调用 super 。

于 2018-01-22T08:04:04.303 回答
2

试着打电话[yourCollectionView.collectionViewLayout invalidateLayout];

于 2016-06-28T18:51:49.317 回答
0

在我的情况下,缺少以下代表:

func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
于 2017-11-14T19:18:21.790 回答
-2
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    [collectionView.collectionViewLayout invalidateLayout];
    return 1;
}
于 2016-07-18T03:46:21.417 回答