【问题标题】:Assertion Failure in UICollectionViewData validateLayoutInRect on ios7ios7上的UICollectionViewData validateLayoutInRect中的断言失败
【发布时间】:2013-10-26 21:59:08
【问题描述】:

iOS7 上 UICollectionViewData validateLayoutInRect 中的断言失败。

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

UICollectionViewData validateLayoutInRect 中的断言失败

我从collectionArray 然后self.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 {
}

【问题讨论】:

标签: ios objective-c ios7 xcode5 uicollectionviewlayout


【解决方案1】:

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

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

【讨论】:

  • 我也在做同样的事情,但无济于事。
  • 帮了大忙。节省我大量的时间。
  • 让我很高兴我把其中的一些东西写下来,因为它实际上对某人有帮助。
【解决方案2】:

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

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

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

【讨论】:

  • 您先生是救生员。谢谢。当我使用自定义 FlowLayout 类时,它确实解决了我的问题。
  • 亲吻和鬼鬼祟祟
  • iUser 您可以这样做,或者通过取消选中 prefetch 属性,在情节提要中打开该特定 collection-view 的 Attribute-inspector pan。
【解决方案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];

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

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

      尝试拨打[yourCollectionView.collectionViewLayout invalidateLayout];

      【讨论】:

        【解决方案6】:

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

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

        如需更好地实现invalidateLayoutWithContext,请参阅UICollectionViewLayoutInvalidationContext 的更多信息。

        来自Apple Developer documentation

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

        【讨论】:

          【解决方案7】:

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

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

          【讨论】:

            【解决方案8】:
            - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
                [collectionView.collectionViewLayout invalidateLayout];
                return 1;
            }
            

            【讨论】:

            • 这会导致堆栈溢出。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-08-07
            • 2012-08-01
            • 2015-09-01
            相关资源
            最近更新 更多