2012-10-14 7 views
14

Utilizzando IOS 6 e il nuovo UICollectionView Ho 2 UICollectionViews sul UIViewController e l'utilizzo di uno storyboard ricevo il seguente errore quando si fa clic in tutto l'UICollectionView io non so perché questo sta accadendo e Google restituisce 0 risultati per questo errore ...errore di asserzione in - [UICollectionViewData numberOfItemsBeforeSection:]

2012-10-13 20:30:06.421 MyApp[768:907] Assertion failure in -[UICollectionViewData numberOfItemsBeforeSection:], /SourceCache/UIKit/UIKit-2372/UICollectionViewData.m:415
2012-10-13 20:30:06.427 MyApp[768:907] Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'request for number of items before section 2147483647 when there are only 1 sections in the collection view'

non sto usando Sezioni a tutti e lo hanno impostato a solo 1 sezione:

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

Succede (sembra essere casuale) quando scatto sopra sulla superficie UICollectionView Ho un pezzo di codice per rimuovere elemento dalla UICollectionView:

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

Ecco come le matrici agganciati al 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; 
    } 
} 

Per favore aiutatemi a risolvere questo problema. Non sono nemmeno sicuro di come sia possibile rilevare l'eccezione poiché proviene dal codice interno di UICollectionView. Inoltre ho dimenticato di menzionare che sto usando un layout personalizzato per UICollectionView ma non so se è correlato a questo problema.

Grazie ancora per il vostro aiuto ragazzi!

Edit: sto ottenendo l'eccezione dopo che tutti i metodi di layout sono chiamati ... Ecco il mio layout personalizzato ... non sono ancora sicuro di come risolvere il problema dal momento che tutti i miei blocchi try di cattura non intercettare l'errore ...

- (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]); 
    } 
} 
+0

La classe viewController principale utilizzata implementa il protocollo UICollectionViewDataSource? Hai impostato il tuo viewController (o qualsiasi altra cosa) come dataSource per UICollectionView? – Cashew

+0

Sì. Implementa 2 protocolli: UICollectionViewDelegate e UICollectionViewDataSource. L'ho impostato come dataSource e delegato per 2 UICollectionViews su di esso. – user1744168

risposta

6

la chiave qui è questo numero dal vostro errore:

2147483647

questo è il valore numerico del NSNotFound. Da qualche parte nel tuo codice stai facendo qualcosa come indexOfObject: contro un array, e passando il risultato di questo in una delle tue view o metodi di layout come una sezione o un indice, che sta causando l'errore. Questo non sta accadendo nel codice pubblicato nella tua domanda, ma spero che tu possa trovarlo ora.

+1

sembra che il problema stia arrivando a causa del mio layout personalizzato ... – user1744168

4

Mi sono appena imbattuto in questa affermazione. Ha sparato perché stavo ricaricando i dati della raccolta su un evento touch (swipe).

Il tocco iniziale (inizio) ha attivato un messaggio didHighlightItemAtIndexPath: e successivamente i dati di raccolta modificati (tramite lo scorrimento), quindi non è riuscito a attivare il messaggio didUnhighlightItemAtIndexPath: sul touch (sollevamento).

Dal momento non ho bisogno di sottolineare, la soluzione era quella di implementare questo metodo nel mio controller:

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

Mi auguro che aiuta chiunque altro in esecuzione in questo.

+1

Volevo solo dire che il problema che avevo riguardava il ricaricamento dei dati della raccolta in un evento con tocco lungo. Rimozione di reloadData risolto il mio problema. –

9

Ho avuto questo problema durante l'esecuzione di reloadData da un riconoscitore di gesti, impostando i ritardi TouchesBegan sul riconoscimento dei gesti.

3

Non ricaricare mai i dati di UICOllectionView su un metodo eseguito da un riconoscitore di gesti.Seguendo questa regola completamente risolto questo problema. Il suggerimento di Daltsy di disattivare Highligting in UICollectionView impedisce anche l'errore, ma disattiva anche tutti i messaggi delegati "didSelectItemAtIndexPath". Fai attenzione perché potresti ritrovarti con un UICollectionView quasi inutile, come ho fatto un paio di minuti fa.

5

questo ha funzionato per me:

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

Eventuali modifiche alla GUI devono essere attivate da un thread principale. Quando si modifica o si aggiorna UICollectionView da un blocco, un delay o un gesture di riconoscimento, è necessario inviarlo sulla coda principale (come descritto da @ Hampden123 sopra). – ripegooseberry

0

Invece di disattivare l'evidenziazione, ho scoperto che fare in modo che non le cellule sono evidenziate prima di chiamare reloadData impedisce la "richiesta di numero di voci prima sezione" errore. È il

UICollectionViewController.CollectionView.deselectItemAtIndexPath metodo o DeselectItem in Xamarin.

Salva un handle sull'elemento attualmente selezionato nei dati del modello, cancella l'evidenziazione della vista dell'insieme, calcola il nuovo NSIndexPaths per gli elementi e quindi chiama reloadData. L'elemento selezionato in precedenza viene nuovamente selezionato utilizzando l'handle per trovarlo tramite la sua possibilmente nuova proprietà NSIndexPath.

selectItemAtIndexPath:animated:scrollPosition: o SelectItem in Xamarin.

Problemi correlati