ios7上的UICollectionViewData validateLayoutInRect中的断言失败

时间:2013-10-18 06:42:44

标签: ios objective-c ios7 xcode5 uicollectionviewlayout

iOS7上UICollectionViewData validateLayoutInRect的断言失败。

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

  

UICollectionViewData中的断言失败validateLayoutInRect

我使用collectionArrayself.collectionView然后indexPath逐个删除对象。当我删除第4个对象时,它会在iOS7上引发Assertion failure。我在这里使用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 {
}

8 个答案:

答案 0 :(得分: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];

答案 1 :(得分:19)

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

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

//Obj C
if ([self.collectionView respondsToSelector:@selector(setPrefetchingEnabled:)]) {
    self.collectionView.prefetchingEnabled = false;
}

答案 2 :(得分:3)

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

[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];

以便所有更新一起执行。否则,您最终会尝试在彼此之上执行多次批量更新。

答案 3 :(得分:3)

layout lifecycle

您应该在layoutClass中实施 invalidateLayout ,并删除配置中的各种UICollectionViewLayoutAttributes项。

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

答案 4 :(得分:1)

尝试拨打[yourCollectionView.collectionViewLayout invalidateLayout];

答案 5 :(得分:1)

您应该在布局类中实现invalidateLayout,并删除配置中的所有UICollectionViewLayoutAttributes项。

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

有关实施invalidateLayoutWithContext的更好方法,请参阅有关UICollectionViewLayoutInvalidationContext

的更多信息

来自Apple Developer documentation

  

实现自定义布局时,您可以覆盖此方法并使用   它处理自定义失效上下文提供的信息。   您不需要提供自定义的失效上下文,但可能   如果您能够提供可以提供帮助的其他属性,请执行此操作   优化布局更新。如果覆盖此方法,则必须调用   超级在你的实施中的某个时刻。

答案 6 :(得分:0)

在我的情况下,代理人失踪了:

func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }

答案 7 :(得分:-1)

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    [collectionView.collectionViewLayout invalidateLayout];
    return 1;
}