コレクションビューから画像の1つのバッチをアンロードしてから別のバッチに置き換えようとすると、エラーが発生し、元の画像グループまたは後続の画像グループが意図した置換よりも多かったり少なかったりするため、次のようなアサーションエラーが発生します。
*** 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でした。したがって、3番目の画像に到達すると-例外が発生し-UI CollectionViewDataDelegateがデータストリームの変更を認識しなかったことを示します。
新しい画像がUICollectionViewによって参照されることを確認する方法に関する提案はありますか?もちろん、「reloadData」と呼ばれています…
ありがとうございました
私は同じ問題を抱えています。コードが6.1で実行され、7.0でクラッシュする次の方法で問題を解決しました。
機能で
-(NSInteger) numberOfSectionsInCollectionView:(UICollectionView *)collectionView
電話する
[myCollectionView.collectionViewLayout invalidateLayout];
それで全部です。
IOS 10および11では、これは次のことに役立ちます。
collectionView.reloadData()
collectionView.collectionViewLayout.invalidateLayout()
無効化レイアウトは、データの再ロード後でなければなりません。
Dominic Sander と ser1544494 の両方が適切であり、それらのソリューションは優れています。
残念ながら、minimumLineSpacingForSectionAtIndex
またはminimumInteritemSpacingForSectionAtIndex
を設定すると、collectionViewの外観が壊れる(遅かれ早かれ)ことに気付きました。
invalidateLayout
にviewWillLayoutSubviews
を入れると、この質問に答え、viewCollectionの外観を維持するのに役立ちます。
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
[viewCollection.collectionViewLayout invalidateLayout];
}
簡単だ。次の文のように。
'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を返します。
UISolutionにのみ存在するUICollectionViewLayoutAttributesを返す必要があります。
IOS7から変更されたと思います。
私の問題は、1つのUICollectionViews
の中に2つのUIViewController
があったことです。そして、両方のUICollectionViews
を同じUICollectionViewLayout
サブクラスに接続しました。各UICollectionView
を独自のUICollectionViewLayout
サブクラスを持つように変更して、この問題を修正しました。
ソース: この質問
コレクションビューのデータソースを更新することで、このクラッシュを修正しました。
- (NSInteger)collectionView:(UICollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section
{
[collectionView.collectionViewLayout invalidateLayout];
return collectionArray.count;
}
同じクラッシュがありました。
私のアプリの問題は、UICollectionViewLayoutAttributesで配列を空にしないことでした。 prepareLayout()メソッドで使用して、各セルのレイアウト属性を保存します。
var itemAttributes: Array<UICollectionViewLayoutAttributes> = Array<UICollectionViewLayoutAttributes>()
PrepareLayoutの最初の行にself.itemAttributes.removeAll()
があれば、機能します。
コレクションビューの内容を変更した後、この問題が発生しました。私の場合、解決したのはリロード後にレイアウトを無効にすることでした。リロードの前に実行すると機能しません。
[collectionView reloadData];
//forces the layout attributes to be recalculated for new data
[collectionView.collectionViewLayout invalidateLayout];
私が見つけた解決策は、layoutAttributesForElementsInRect(rect: CGRect) -> [AnyObject]?
メソッドで作成していたindexPath
が行に対して有効であることを確認することでした。以前、私は使用していました(i
はループカウンターです):
var indexPath = NSIndexPath(index: i)
var attributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)
しかし、以下を使用するように更新すると解決しました:
var indexPath = NSIndexPath(forRow: i, inSection: 0)!
var attributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)
UICollectionViewFlowLayout
のサブクラスを作成し、このメソッドをオーバーライドしてYES
を返すことにより、この問題を解決できました。
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
return YES;
}
コレクションビューを別のストーリーボードに複製しようとすると、似たようなことが起こりました。
「UICollectionViewは、存在しないインデックスパスを持つセルのレイアウト属性を受け取りました:{length = 2、path = 1-0}」
最初は、簡単な修正方法を探しています。 StackOverflowのさまざまな回答をコピーして貼り付けてみました。
しかし、独自のレイアウトクラスを作成しました。だから私は慎重にデバッグしようとしますが、それは私の実装のせいかもしれませんよね? numberOfSections
メソッドが呼び出されたことはありませんでした。コレクションビューは、セクションが1つしかないことを前提としています。
次に、View ControllerクラスがUICollectionViewDataSource
に準拠するのを忘れていることがわかりました。 dataSourceはストーリーボードに接続されましたが、おそらくView Controllerクラスはif let ds = dataSource as? UICollectionViewDataSource {ds.numberOfSections...}
、これは静かに失敗します。
そこで、UICollectionViewDataSource
に適合性を追加しましたが、すべて正常に動作します。私の推測は不正確かもしれません。しかし、教訓は、あなたがよく知らないバグがあり、落ち着いてそれを理解するときです。 UICollectionViewは、存在しないインデックスパスを持つセルのレイアウト属性を受け取りました、それはまさにそれが言っていることを意味します。そんなに難しくありませんか?ここにある多くの答えのように、特効薬を見つけようとしないでください。それらはすべて素晴らしいですが、あなたのコードは本当の戦いの場です。
私の場合、カスタムUICollectionViewFlowLayout
がありました。 collectionViewからセルを削除すると、アプリがクラッシュしました。修正は、以前に計算されたremoveAll()
属性に対するものでした。したがって、override func prepare()
の後の最初の行はarrayHoldingYourAttributes.removeAll()
です。
私はこの問題に遭遇しましたが、かなり面倒でした。私の修正は、UICollectionViewController
を忘れ、代わりにUIViewController
を含む通常のUICollectionView
を使用することです。
これは、dataSouceにindexPath(0,2)がないことを意味します。ただし、UICollectionViewLayoutはindexPath(0,2)のUICollectionViewLayoutAttributesを返します。 TopChulによる
そのとおり!私にとっては、2つのcollectionViewにsame collection layout(instance)を使用しているため、問題が発生しました!そのため、そのレイアウトは2つのコレクションビュー間で混同されます。
異なるコレクションビュー間で異なるレイアウトを使用した後、正常に動作します。
私もこのバグを抱えており、回避策を見つけました。私にとって、UICollectionViewはiOS 7でこれを起動し、iOS 8で完全に動作していました。
この記事を確認してください: このiOSクラッシュの原因は何ですか?UICollectionViewは、存在しないインデックスパスを持つセルのレイアウト属性を受け取りました
2語で:自動レイアウト。 UICollectionViewを含むビューでそれを無効にすると、私にとっては機能しました。
contentSize
のcollectionViewLayout
を必ず更新してください。そのため、新しい画像(5ではなく2)を取得した後、contentSize
を再計算して設定します。
同様の問題がありました(Swift2.0、XCode 7を使用)。
アプリはUICollectionView received layout attributes for a cell with an index path that does not exist
...でクラッシュしました.
私の場合、ストーリーボードを使用したため、viewControllerで定義されたIBOutletをストーリーボードで定義された実際のcollectionViewに接続するのを忘れたことがわかりました。この2つを接続すると問題が解決しました。
UICollectionViewFlowLayout
をCollectionView's collectionViewLayout
として使用すると、同じ問題が発生します。
親を宣言viewController
実装UICollectionViewDelegateFlowLayout
し、collectionView
のデリゲートとして割り当てると、この問題を解決できます。
私はそれを理解しました。 nib/xibを使用してUITableViewCell
およびネストされたUICollectionView
を整理している場合、このメソッドをオーバーライドすることでこのエラーを回避できます。
- (void)prepareForReuse {
[super prepareForReuse];
[self.collectionView.collectionViewLayout invalidateLayout];
}
それが役に立てば幸い。
CollectionViewLayoutは、レイアウト属性をキャッシュします。ビューに表示されます。 collectionViewLayoutの新しいインスタンスを作成し、collectionview.collectionViewLayoutに割り当てます。これにより、リロードの前にすべてのキャッシュされた属性が消去されます。問題が解決する可能性があります。特に他のcollectionViewLayoutライブラリを使用している場合は、私のために働いた。