14

IOS 6と新しいUICollectionViewを使用すると、UIViewControllerに2つのUICollectionViewがあり、ストーリーボードを使用すると、UICollectionViewをクリックすると、次のエラーが発生します。なぜこれが発生するのかわからないため、Googleはこのエラーに対して0の結果を返します...

2012-10-13 20:30:06.421 MyApp [768:907]-[UICollectionViewData numberOfItemsBeforeSection:]でのアサーションの失敗、/ SourceCache / UIKit / UIKit-2372 / UICollectionViewData.m:415
2012-10-13 20:30:06.427 MyApp [768:907]キャッチされなかった例外'NSInternalInconsistencyException'が原因でアプリを終了しています、理由:'コレクションビューにセクションが1つしかない場合に、セクション2147483647より前のアイテム数をリクエストします'

セクションをまったく使用しておらず、1つのセクションに設定しています。

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 1;
}

UICollectionView領域をクリックすると、発生します(ランダムに表示されます)。UICollectionViewから要素を削除するコードがあります。

[tilesArray removeObjectAtIndex:indexPath.row];
[self.tilesCollectionView reloadData];        
[resultsArray addObject:str];
[self.resultsCollectionView reloadData];

配列がUICollectionViewsに接続された方法は次のとおりです

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {

    if(collectionView.tag == 2)
        return [resultsArray count];
    else
        return [tilesArray count];
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

    if(collectionView.tag == 2)
    {
        static NSString *cellIdentifier = @"ResultCell";
        ResultCell *cell = (ResultCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];

        cell.mainImage.image = [UIImage imageNamed:currentArtContainer.tileMainImage];

        NSString *cellData = [resultsArray objectAtIndex:indexPath.row];
        [cell.titleLabel setText:cellData];

        return cell;
    }
    else
    {
        static NSString *cellIdentifier = @"TileCell";
        TileCell *cell = (TileCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];

        cell.topImage.image = [UIImage imageNamed:currentArtContainer.tileTopImage];

        cell.mainImage.image = [UIImage imageNamed:currentArtContainer.tileMainImage];

        NSString *cellData = [tilesArray objectAtIndex:indexPath.row];
        [cell.titleLabel setText:cellData];

        return cell;
    }
}

この問題の解決にご協力ください。UICollectionViewの内部コードから発生しているため、例外をどのようにキャッチできるかさえわかりません。また、UICollectionViewにカスタムレイアウトを使用していることにも言及するのを忘れましたが、それがこの問題に関連しているかどうかはわかりません。

助けてくれてありがとう!

編集:すべてのレイアウトメソッドが呼び出された後に例外が発生します...これが私のカスタムレイアウトです...すべてのtry catchブロックがエラーをトラップしないため、修正方法がまだわかりません。 ..

- (void)prepareLayout
{
    NSLog(@"In prepareLayout.");

    [super prepareLayout];
    _cellCount = [[self collectionView] numberOfItemsInSection:0];
}

- (CGSize)collectionViewContentSize
{
    NSLog(@"In collectionViewContentSize.");
    @try {

       CGSize csize = [self collectionView].frame.size;
        NSLog(@"In here.");
        return csize;
    }
    @catch(NSException *exception)
    {
        NSLog(@"collectionViewContentSize %@: %@",[exception name],[exception reason]);
    }

}

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
    @try {

    NSLog(@"In layoutAttributesForItemAtIndexPath. item %d", indexPath.row);


    UICollectionViewLayoutAttributes* attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];

    attributes.size = CGSizeMake(ITEM_SIZE, ITEM_SIZE);

    NSLog(@"firstRun %d", self.firstRun);
    //NSLog(@"panStatus %@", self.panStatus);

    if (self.firstRun == 0) {
        CGFloat x = 0, y = 0;
        CGFloat boundx = self.collectionView.frame.size.width * 0.70;   // Use the whole canvas
        CGFloat boundy = self.collectionView.frame.size.height * 0.70; // Use the whole canvas
        while (x < 50 || x > boundx) x = arc4random() % (int)boundx + indexPath.item;
        while (y < 50 || y > boundy) y = arc4random() % (int)boundy + indexPath.item;

        NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
        if (self.positions)
            dictionary = [self.positions mutableCopy];
        [dictionary setObject:[NSValue valueWithCGPoint:CGPointMake(x, y)] forKey:@(indexPath.item)];
        if (!self.positions)
            self.positions = [[NSDictionary alloc] init];
        self.positions = dictionary;

        attributes.center = CGPointMake(x, y);
    } else if (self.firstRun > 0) {
        CGPoint point = [[self.positions objectForKey:@(indexPath.item)] CGPointValue];
        attributes.center = CGPointMake(point.x, point.y);
    }

    NSLog(@"END layoutAttributesForItemAtIndexPath. item %d", indexPath.row);
        return attributes;

    }
    @catch(NSException *exception)
    {
        NSLog(@"layoutAttributesForItemAtIndexPath %@: %@",[exception name],[exception reason]);
    }
}

-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    @try {

    NSLog(@"layoutAttributesForElementsInRect ...");

    NSMutableArray* attributes = [NSMutableArray array];
    for (NSInteger i=0 ; i < self.cellCount; i++) {
        NSIndexPath* indexPath = [NSIndexPath indexPathForItem:i inSection:1];
        [attributes addObject:[self layoutAttributesForItemAtIndexPath:indexPath]];
    }
    NSLog(@"END layoutAttributesForElementsInRect ...");
        return attributes;

    }
    @catch(NSException *exception)
    {
        NSLog(@"layoutAttributesForElementsInRect %@: %@",[exception name],[exception reason]);
    }
}
4

6 に答える 6

9

ジェスチャ認識エンジンから reloadData を実行すると、これが発生しました。ジェスチャ認識エンジンでdelaysTouchesBeganを設定すると役立ちました。

于 2013-02-03T18:39:01.530 に答える
6

ここでのキーは、エラーからのこの番号です。

2147483647

これは の数値ですNSNotFound。コードのどこかでindexOfObject:配列に対して何かを行っており、その結果をセクションまたはアイテム インデックスとしてコレクション ビューまたはレイアウト メソッドの 1 つに渡しているため、エラーが発生しています。これは、質問に投稿されたコードでは発生していませんが、今すぐ見つけられることを願っています。

于 2012-10-14T07:10:13.747 に答える
5

これは私のために働いた:

dispatch_async(dispatch_get_main_queue(), ^{
    [self.collectionView reloadData];
});
于 2013-06-06T14:33:29.007 に答える
4

私はちょうどこの主張に出くわしました。タッチ(スワイプ)イベントでコレクションデータをリロードしていたために発生しました。

最初のタッチ (begin) でdidHighlightItemAtIndexPath:メッセージがトリガーされ、次に (スワイプによって) コレクション データが変更さdidUnhighlightItemAtIndexPath:れ、タッチ (lift) でメッセージのトリガーに失敗しました。

強調表示する必要がないため、解決策はこのメソッドをコントローラーに実装することでした。

- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath
{
    return NO;
}

これが他の誰かがこれに遭遇するのに役立つことを願っています。

于 2013-01-09T18:44:41.797 に答える
3

ジェスチャ レコグナイザーによって実行されるメソッドで、UICollectionView のデータを再読み込みしないでください。このルールに従うことで、この問題は完全に解決されました。UICollectionView で強調表示を無効にするという Daltsy の提案もエラーを防ぎますが、すべての "didSelectItemAtIndexPath" デリゲート メッセージも無効にします。数分前に行ったように、ほとんど役に立たない UICollectionView になる可能性があるので注意してください。

于 2013-02-09T09:58:31.460 に答える
0

強調表示を無効にする代わりに、reloadData を呼び出す前にセルが強調表示されていないことを確認すると、「セクションの前に項目数を要求する」というエラーが防止されることがわかりました。それは

UICollectionViewController.CollectionView.deselectItemAtIndexPath メソッドまたはDeselectItemXamarin で。

モデル データで現在選択されている項目へのハンドルを保存し、コレクション ビューの強調表示をクリアし、項目の新しい NSIndexPaths を計算してから、reloadData を呼び出します。以前に選択された項目は、ハンドルを使用して、新しい NSIndexPath プロパティを介して検索することにより、再度選択されます。

selectItemAtIndexPath:animated:scrollPosition:またはSelectItemXamarinで。

于 2015-12-02T09:35:01.887 に答える