IOS7でのUICollectionViewData
validateLayoutInRect
でのアサーションエラー。
UICollectionView
ループを使用して、すべてのfor
アイテムを1つずつ削除しようとしています。以下のコードを投稿しました。 UICollectionView
を使用してdeleteItemsAtIndexPaths
アイテムを削除します。これはiOS6で完全に機能するですが、iOS7ではクラッシュですが、次の例外があります。
UICollectionViewData validateLayoutInRectでのアサーションエラー
collectionArray
からオブジェクトを削除し、次にindexPath
を使用してself.collectionView
を1つずつ削除します。 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 {
}
実際にこのクラッシュが発生したのは、セクションまたはセクション内のアイテムの数に対してゼロを返したからではなく、次のようなフローレイアウトを複数のコレクションビューで再利用したためです。
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];
iOS 10では、prefetchingEnabledを無効にする必要があります。
// Swift
if #available(iOS 10, *) {
collectionView.prefetchingEnabled = false
}
//Obj C
if ([self.collectionView respondsToSelector:@selector(setPrefetchingEnabled:)]) {
self.collectionView.prefetchingEnabled = false;
}
おそらくこれを実行したいようです:
[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];
すべての更新が一緒に実行されるようにします。そうしないと、複数のバッチ更新を重ねて実行しようとすることになります。
layoutClass
にinvalidateLayoutを実装し、構成内のすべての種類のUICollectionViewLayoutAttributes
項目を削除する必要があります。
- (void)invalidateLayout{
[super invalidateLayout];
[self.itemsAttributes removeAllObjects];
}
[yourCollectionView.collectionViewLayout invalidateLayout];
を呼び出してみてください
レイアウトクラスにinvalidateLayoutを実装し、すべての種類のUICollectionViewLayoutAttributes
項目を構成から削除する必要があります。
- (void)invalidateLayout{
[super invalidateLayout];
[self.itemsAttributes removeAllObjects];
}
invalidateLayoutWithContext
を実装するより良い方法については、UICollectionViewLayoutInvalidationContext
の詳細をご覧ください。
カスタムレイアウトを実装する場合、このメソッドをオーバーライドして、カスタム無効化コンテキストによって提供される情報を処理するために使用できます。カスタム無効化コンテキストを提供する必要はありませんが、レイアウトの更新を最適化するのに役立つ追加のプロパティを提供できる場合は、そうする可能性があります。このメソッドをオーバーライドする場合は、実装のある時点でsuperを呼び出す必要があります。
私の場合、次のデリゲートがありませんでした:
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}