web-dev-qa-db-ja.com

古いデータでのUICollectionViewアサーションエラー

コレクションビューから画像の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」と呼ばれています…

ありがとうございました

60
user1686700

私は同じ問題を抱えています。コードが6.1で実行され、7.0でクラッシュする次の方法で問題を解決しました。

機能で

-(NSInteger) numberOfSectionsInCollectionView:(UICollectionView *)collectionView

電話する

[myCollectionView.collectionViewLayout invalidateLayout];

それで全部です。

85
Dominic Sander

IOS 10および11では、これは次のことに役立ちます。

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

無効化レイアウトは、データの再ロード後でなければなりません。

22

Dominic Sanderser1544494 の両方が適切であり、それらのソリューションは優れています。

残念ながら、minimumLineSpacingForSectionAtIndexまたはminimumInteritemSpacingForSectionAtIndexを設定すると、collectionViewの外観が壊れる(遅かれ早かれ)ことに気付きました。

invalidateLayoutviewWillLayoutSubviewsを入れると、この質問に答え、viewCollectionの外観を維持するのに役立ちます。

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];
    [viewCollection.collectionViewLayout invalidateLayout];
}
21
Beppe

簡単だ。次の文のように。

'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から変更されたと思います。

12
TopChul

私の問題は、1つのUICollectionViewsの中に2つのUIViewControllerがあったことです。そして、両方のUICollectionViewsを同じUICollectionViewLayoutサブクラスに接続しました。各UICollectionViewを独自のUICollectionViewLayoutサブクラスを持つように変更して、この問題を修正しました。

ソース: この質問

10
Johann Burgess

コレクションビューのデータソースを更新することで、このクラッシュを修正しました。

- (NSInteger)collectionView:(UICollectionView *)collectionView
     numberOfItemsInSection:(NSInteger)section
{
    [collectionView.collectionViewLayout invalidateLayout];
    return collectionArray.count;
}
4
megha

同じクラッシュがありました。

私のアプリの問題は、UICollectionViewLayoutAttributesで配列を空にしないことでした。 prepareLayout()メソッドで使用して、各セルのレイアウト属性を保存します。

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

PrepareLayoutの最初の行にself.itemAttributes.removeAll()があれば、機能します。

2
Beuj

コレクションビューの内容を変更した後、この問題が発生しました。私の場合、解決したのはリロード後にレイアウトを無効にすることでした。リロードの前に実行すると機能しません。

[collectionView reloadData];

//forces the layout attributes to be recalculated for new data
[collectionView.collectionViewLayout invalidateLayout];
2
ricosrealm

私が見つけた解決策は、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)
1
Sam Youtsey

UICollectionViewFlowLayoutのサブクラスを作成し、このメソッドをオーバーライドしてYESを返すことにより、この問題を解決できました。

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
    return YES;
}
1
Snowman

コレクションビューを別のストーリーボードに複製しようとすると、似たようなことが起こりました。

「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は、存在しないインデックスパスを持つセルのレイアウト属性を受け取りました、それはまさにそれが言っていることを意味します。そんなに難しくありませんか?ここにある多くの答えのように、特効薬を見つけようとしないでください。それらはすべて素晴らしいですが、あなたのコードは本当の戦いの場です。

0
jchnxu

私の場合、カスタムUICollectionViewFlowLayoutがありました。 collectionViewからセルを削除すると、アプリがクラッシュしました。修正は、以前に計算されたremoveAll()属性に対するものでした。したがって、override func prepare()の後の最初の行はarrayHoldingYourAttributes.removeAll()です。

0
Pantelis Proios

私はこの問題に遭遇しましたが、かなり面倒でした。私の修正は、UICollectionViewControllerを忘れ、代わりにUIViewControllerを含む通常のUICollectionViewを使用することです。

0
Pavel Sharanda

これは、dataSouceにindexPath(0,2)がないことを意味します。ただし、UICollectionViewLayoutはindexPath(0,2)のUICollectionViewLayoutAttributesを返します。 TopChulによる

そのとおり!私にとっては、2つのcollectionViewにsame collection layout(instance)を使用しているため、問題が発生しました!そのため、そのレイアウトは2つのコレクションビュー間で混同されます。

異なるコレクションビュー間で異なるレイアウトを使用した後、正常に動作します。

0

私もこのバグを抱えており、回避策を見つけました。私にとって、UICollectionViewはiOS 7でこれを起動し、iOS 8で完全に動作していました。

この記事を確認してください: このiOSクラッシュの原因は何ですか?UICollectionViewは、存在しないインデックスパスを持つセルのレイアウト属性を受け取りました

2語で:自動レイアウト。 UICollectionViewを含むビューでそれを無効にすると、私にとっては機能しました。

0
Eric Giguere

contentSizecollectionViewLayoutを必ず更新してください。そのため、新しい画像(5ではなく2)を取得した後、contentSizeを再計算して設定します。

0

同様の問題がありました(Swift2.0、XCode 7を使用)。

アプリはUICollectionView received layout attributes for a cell with an index path that does not exist...でクラッシュしました.

私の場合、ストーリーボードを使用したため、viewControllerで定義されたIBOutletをストーリーボードで定義された実際のcollectionViewに接続するのを忘れたことがわかりました。この2つを接続すると問題が解決しました。

0
da-na

UICollectionViewFlowLayoutCollectionView's collectionViewLayoutとして使用すると、同じ問題が発生します。

親を宣言viewController実装UICollectionViewDelegateFlowLayoutし、collectionViewのデリゲートとして割り当てると、この問題を解決できます。

0
ChaoTangChang

私はそれを理解しました。 nib/xibを使用してUITableViewCellおよびネストされたUICollectionViewを整理している場合、このメソッドをオーバーライドすることでこのエラーを回避できます。

- (void)prepareForReuse {

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

それが役に立てば幸い。

0
tounaobun

CollectionViewLayoutは、レイアウト属性をキャッシュします。ビューに表示されます。 collectionViewLayoutの新しいインスタンスを作成し、collectionview.collectionViewLayoutに割り当てます。これにより、リロードの前にすべてのキャッシュされた属性が消去されます。問題が解決する可能性があります。特に他のcollectionViewLayoutライブラリを使用している場合は、私のために働いた。

0
Ankish Jain