61

在尝试从我的收藏视图中卸载一批图像然后用另一批替换它们的过程中,我遇到了一个错误,根据原始图像组或后续图像组是多于还是少于预期的替换,一个发生断言错误,它说:

*** Assertion failure in -[UICollectionViewData validateLayoutInRect:], 
/SourceCache/UIKit_Sim/UIKit-2891.1/UICollectionViewData.m:341
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', 
reason: 'UICollectionView recieved layout attributes for a cell with an 
index path that does not exist: <NSIndexPath: 0xb141c60> {length = 2, path = 0 - 2}

在这种情况下,现有的图像计数列表为 5,而新的图像计数列表为 2。因此,当它到达第三张图像时 - 发生了异常 - 表明 UI CollectionViewDataDelegate 不知道数据流中的变化.

关于如何确保 UICollectionView 引用新图像的任何建议?当然,我已经调用了“reloadData”……

谢谢

4

21 回答 21

85

我遇到了同样的问题。代码在 6.1 下运行并在 7.0 下崩溃我通过以下方式解决了这个问题:

在函数中

-(NSInteger) numberOfSectionsInCollectionView:(UICollectionView *)collectionView

我打电话

[myCollectionView.collectionViewLayout invalidateLayout];

就这样。

于 2013-10-15T10:16:04.680 回答
22

在 iOS 10 和 11 中,这有助于:

collectionView.reloadData()
collectionView.collectionViewLayout.invalidateLayout()

无效布局应该在重新加载数据之后。

于 2016-12-27T14:22:39.880 回答
21

Dominic Sanderuser1544494都是对的,他们的解决方案也很好。

不幸的是,我注意到,如果您设置minimumLineSpacingForSectionAtIndexor minimumInteritemSpacingForSectionAtIndex,您的 collectionView 的外观将会损坏(迟早)。

invalidateLayout加入回答了这个问题并有助于保留viewCollectionviewWillLayoutSubviews的外观。

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];
    [viewCollection.collectionViewLayout invalidateLayout];
}
于 2014-01-21T14:53:28.307 回答
12

这很简单。就像下面这句话一样。

'UICollectionView recieved layout attributes for a cell with an 
index path that does not exist: <NSIndexPath: 0xb141c60> {length = 2, path = 0 - 2}

这意味着 dataSouce 上没有 indexPath(0,2)。但是,您的 UICollectionViewLayout 返回 indexPath(0,2) 的 UICollectionViewLayoutAttributes。

您应该返回 UICollectionViewLayoutAttributes 只存在于 dataSouce 上。


我认为它是从 iOS7 改变的。

于 2013-09-25T09:12:52.817 回答
10

我的问题是我有两个UICollectionViews里面一个UIViewController。而且我都UICollectionViews连接到同一UICollectionViewLayout个子类。我通过将每个更改UICollectionView为拥有自己的UICollectionViewLayout子类来解决此问题。

来源:这个问题

于 2014-08-25T10:30:01.653 回答
4

I fixed this crash by updating my collection view data source :

- (NSInteger)collectionView:(UICollectionView *)collectionView
     numberOfItemsInSection:(NSInteger)section
{
    [collectionView.collectionViewLayout invalidateLayout];
    return collectionArray.count;
}
于 2014-01-14T12:24:49.623 回答
2

我在修改 Collection View 的内容后遇到了这个问题。在我的情况下有效的解决方案是在重新加载后使布局无效。在重新加载之前这样做是行不通的。

[collectionView reloadData];

//forces the layout attributes to be recalculated for new data
[collectionView.collectionViewLayout invalidateLayout];
于 2016-12-16T20:51:24.093 回答
2

我有同样的崩溃。

在我的应用程序中,问题是我没有使用 UICollectionViewLayoutAttributes 清空数组。我在 prepareLayout() 方法中使用它来存储每个单元格的布局属性。

var itemAttributes: Array<UICollectionViewLayoutAttributes> = Array<UICollectionViewLayoutAttributes>()

self.itemAttributes.removeAll()在 prepareLayout 的第一行中,它就可以工作。

于 2016-01-11T09:26:33.293 回答
1

我找到的解决方案是确保indexPath我在layoutAttributesForElementsInRect(rect: CGRect) -> [AnyObject]?方法中创建的行对行有效。以前,我正在使用(i我的循环计数器在哪里):

var indexPath = NSIndexPath(index: i)
var attributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)

但是更新它以使用以下解决了它:

var indexPath = NSIndexPath(forRow: i, inSection: 0)!
var attributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)
于 2015-03-17T20:29:53.820 回答
1

我能够通过创建一个子类UICollectionViewFlowLayout并覆盖这个方法来解决这个问题YES

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
    return YES;
}
于 2015-12-07T17:15:49.790 回答
0

我也遇到过这个错误并找到了解决方法。对我来说,UICollectionView 是在 iOS 7 下启动的,在 iOS 8 上完美运行。

查看这篇文章:是什么导致了这个 iOS 崩溃?UICollectionView 接收到具有不存在索引路径的单元格的布局属性

简而言之:自动布局。在包含 UICollectionView 的视图上禁用它,对我来说,它有效。

于 2015-01-29T19:05:43.817 回答
0

我遇到了这个问题,这很烦人。我的解决方法是忘记UICollectionViewController并使用内部规则UIViewController代替UICollectionView

于 2013-12-02T22:34:03.217 回答
0

collectionViewLayout 缓存布局属性。在视图中会出现。创建一个新的 collectionViewLayout 实例并将其分配给 collectionview.collectionViewLayout 这样所有缓存的属性将在重新加载之前清除您的问题可能会得到解决。为我工作,尤其是当您使用其他 collectionViewLayout 库时。

于 2015-04-09T13:16:38.800 回答
0

确保更新contentSize您的collectionViewLayout. 因此,在获得新图像(2 个,而不是 5 个)后,重新计算contentSize并设置它。

于 2013-11-06T01:46:05.253 回答
0

这意味着 dataSouce 上没有 indexPath(0,2)。但是,您的 UICollectionViewLayout 返回 indexPath(0,2) 的 UICollectionViewLayoutAttributes。由 TopChul

这是正确的!对我来说,问题的发生是因为我对两个 collectionView 使用了相同的集合布局(实例)!所以两个集合视图之间的布局混淆了。

在不同的集合视图之间使用不同的布局后它工作正常。

于 2016-05-12T03:46:31.710 回答
0

我已经想通了。如果你使用 nib/xib 来组织你的UITableViewCell和嵌套的UICollectionView,你可以通过覆盖这个方法来避免这个错误。

- (void)prepareForReuse {

    [super prepareForReuse];
    [self.collectionView.collectionViewLayout invalidateLayout];
}

希望能帮助到你。

于 2016-02-29T06:55:17.387 回答
0

UICollectionViewFlowLayout当我使用as时,我遇到了同样的问题CollectionView's collectionViewLayout

声明父viewController实现UICollectionViewDelegateFlowLayout并将其分配为collectionView' 代表可以解决这个问题。

于 2017-01-18T16:22:29.917 回答
0

我有类似的问题(使用 Swift2.0,XCode 7)。

该应用程序崩溃了UICollectionView received layout attributes for a cell with an index path that does not exist...

就我而言,由于我使用了情节提要,结果我忘记将我的 viewController 中定义的 IBOutlet 与情节提要中定义的实际 collectionView 连接起来。将两者连接起来解决了这个问题。

于 2016-02-27T18:59:38.637 回答
0

就我而言,我有一个习惯UICollectionViewFlowLayout。从 collectionView 中删除单元格后,应用程序崩溃了。修复是针对removeAll()先前计算的属性。所以,之后的第一行override func prepare()arrayHoldingYourAttributes.removeAll().

于 2019-01-30T14:49:56.547 回答
0

尝试将集合视图复制到另一个故事板时,我遇到了类似的情况。

'UICollectionView 接收到具有不存在索引路径的单元格的布局属性:{length = 2, path = 1 - 0}'

起初,我正在寻找快速解决方案。尝试复制粘贴各种 StackOverflow 答案。

但是我写了自己的布局类。所以我尝试谨慎地调试,这可能是我的执行问题,对吧?发现numberOfSections从未调用过该方法。集合视图假设它只有一个部分。

然后我发现视图控制器类忘记符合UICollectionViewDataSource. 尽管 dataSource 已连接到情节提要中,但视图控制器类可能会被向下转换,例如if let ds = dataSource as? UICollectionViewDataSource {ds.numberOfSections...},它会默默地失败。

所以我添加了一致性UICollectionViewDataSource,一切正常。我的猜测可能不准确。但教训是每当有一个你不熟悉的错误时,安顿下来并理解它。UICollectionView 收到的单元格的布局属性具有不存在的索引路径,这正是它所说的。没那么难吧?不要试图找到灵丹妙药,就像这里的许多答案一样。它们都很棒,但你的代码才是真正的战场。

于 2016-12-13T08:20:37.200 回答
-2

你好,我在将一个 collectionView 插入另一个 collectionView 并在主队列中 reloadData 时遇到了同样的问题。最后,我在新数据转换为 collectionView 之前重新加载数据。

dispatch_async(dispatch_get_main_queue(), ^{
    [_collectionView reloadData];
});

_notes = notes;

[_collectionView reloadData];
于 2015-12-24T05:04:06.313 回答