簡體   English   中英

斷言失敗 - [UICollectionViewData numberOfItemsBeforeSection:]

[英]Assertion failure in -[UICollectionViewData numberOfItemsBeforeSection:]

使用IOS 6和新的UICollectionView我在UIViewController上有兩個UICollectionView並使用一個Storyboard當我點擊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之前的項目數'

我根本沒有使用Sections,只將它設置為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]);
    }
}

我從手勢識別器運行reloadData時遇到這種情況,在手勢識別上設置delayedTouchesBegan幫助。

這里的關鍵是你的錯誤中的這個數字:

2147483647

這是NSNotFound的數值。 在代碼中的某處,您正在執行類似indexOfObject:針對數組,並將其結果作為段或項索引傳遞到您的一個集合視圖或布局方法中,這會導致錯誤。 在您的問題中發布的代碼中沒有發生這種情況,但希望您現在能夠找到它。

這對我有用:

dispatch_async(dispatch_get_main_queue(), ^{
    [self.collectionView reloadData];
});

我自己就碰到了這個斷言。 它因為我在觸摸(滑動)事件中重新加載集合數據而被解雇。

初始觸摸(開始)觸發了didHighlightItemAtIndexPath:消息,接下來集合數據發生了變化(通過滑動),然后觸摸(提升)時無法觸發didUnhighlightItemAtIndexPath:消息。

由於我不需要突出顯示,解決方案是在我的控制器中實現此方法:

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

我希望能幫助其他人遇到這個問題。

切勿在手勢識別器執行的方法上重新加載UICOllectionView的數據。 遵循此規則完全解決了這個問題。 Daltsy建議在UICollectionView中停用highligting也可以防止錯誤,但也會停用所有“didSelectItemAtIndexPath”委托消息。 小心,因為你可能最終得到一個幾乎無用的UICollectionView - 就像幾分鍾前我做的那樣。

我沒有禁用突出顯示,而是發現確保在調用reloadData之前沒有突出顯示單元格會阻止“在節之前請求項目數”錯誤。 就是這樣

UICollectionViewController.CollectionView.deselectItemAtIndexPath方法或Xamarin中的DeselectItem

我保存模型數據中當前所選項目的句柄,清除集合視圖的突出顯示,為項目計算新的NSIndexPaths,然后調用reloadData。 通過使用句柄通過其可能的新NSIndexPath屬性來再次選擇先前選擇的項目。

selectItemAtIndexPath:animated:scrollPosition:或Xamarin中的SelectItem

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM