2012-09-24 22 views
6

Si sta tentando di configurare UICollectionView con un layout personalizzato. Il contenuto di ciascuna CollectionViewCell sarà un'immagine. Oltre a tutto ci saranno diverse migliaia di immagini e circa 140-150 sarà visibile in una certa ora. In un evento di azione potenzialmente tutte le celle saranno riorganizzate in posizione e dimensioni. L'obiettivo è animare tutti gli eventi in movimento attualmente utilizzando il metodo performBatchUpdates. Ciò causa un enorme ritardo prima che tutto si animi.UICollectionView Problemi relativi alle prestazioni su performBatchUpdates

Finora abbiamo scoperto che internamente il metodo layoutAttributesForItemAtIndexPath viene chiamato per ogni singola cella (diverse migliaia in totale). Inoltre, il metodo cellForItemAtIndexPath viene chiamato per più celle di quelle che possono effettivamente essere visualizzate sullo schermo.

Esistono possibilità per migliorare le prestazioni dell'animazione?


L'impostazione predefinita UICollectionViewFlowLayout non può realmente offrire il tipo di design che vogliamo realizzare in app. Ecco alcuni dei nostro codice:

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 
RPDataModel *dm = [RPDataModel sharedInstance]; //Singleton holding some global information 
NSArray *plistArray = dm.plistArray; //Array containing the contents of the cells 
NSDictionary *dic = plistArray[[indexPath item]]; 
RPCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CELL" forIndexPath:indexPath]; 
cell.label.text = [NSString stringWithFormat:@"%@",dic[@"name"]]; 
cell.layer.borderColor = nil; 
cell.layer.borderWidth = 0.0f; 
[cell loadAndSetImageInBackgroundWithLocalFilePath:dic[@"path"]]; //custom method realizing asynchronous loading of the image inside of each cell 
return cell; 
} 

I itera layoutAttributesForElementsInRect su tutti gli elementi di impostazione layoutAttributes per tuttiIl elementi all'interno del rettangolo. Le interruzioni per-dichiarazione sulla prima cella essendo oltre i confini definiti dal nell'angolo in basso a destra del rettangolo:

-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect { 
NSMutableArray* attributes = [NSMutableArray array]; 
RPDataModel *dm = [RPDataModel sharedInstance]; 
for (int i = 0; i < dm.cellCount; i++) { 
    CGRect cellRect = [self.rp getCell:i]; //self.rp = custom object offering methods to get information about cells; the getCell method returns the rect of a single cell 
    if (CGRectIntersectsRect(rect, cellRect)) { 
     NSIndexPath *indexPath = [NSIndexPath indexPathForItem:[dm.relevanceArray[i][@"product"] intValue] inSection:0]; 
     UICollectionViewLayoutAttributes *attribute = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; 
     attribute.size = cellRect.size; 
     attribute.center = CGPointMake(cellRect.origin.x + attribute.size.width/2, cellRect.origin.y + attribute.size.height/2); 
     [attributes addObject:attribute]; 
    } else if (cellRect.origin.x > rect.origin.x + rect.size.width && cellRect.origin.y > rect.origin.y + rect.size.height) { 
     break; 
    } 
} 
return attributes; 
} 

Il layout cambia i risultati sono praticamente la stessa, non importa se in fase di definizione il numero di cellule nel layoutAttributesForElementsInRect è limitato o no. O il sistema ottiene gli attributi di layout per tutte le celle in là se non è limitato o chiama il metodo layoutAttributesForElementAtIndexPath per tutte le celle mancanti se è limitato. Nel complesso, gli attributi per ogni singola cella vengono utilizzati in qualche modo.

-(UICollectionViewLayoutAttributes*)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { 
RPDataModel *dm = [RPDataModel sharedInstance]; 
UICollectionViewLayoutAttributes *attribute = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; 
CGRect cellRect = [self.rp getCell:[dm.indexDictionary[@(indexPath.item)] intValue]]; 
attribute.size = cellRect.size; 
attribute.center = CGPointMake(cellRect.origin.x + attribute.size.width/2, cellRect.origin.y + attribute.size.height/2); 
return attribute; 
}  
+0

Inserisci il tuo codice dal tuo UICollectionViewLayout. –

risposta

3

Senza vedere il codice, la mia ipotesi è che il metodo è layoutAttributesForElementsInRect iterazione attraverso tutti gli elementi nella vostra collezione, e che è, a sua volta, che cosa sta causando gli altri metodi per superare cd. layoutAttributesForElementsInRect ti fornisce un suggerimento, ovvero il CGRect che ti sta passando, sugli elementi che devi chiamare layoutAttributesForItemAtIndexPath per, in termini di ciò che è visualizzato sullo schermo.

In modo che possa essere parte del problema di prestazioni, cioè, l'ottimizzazione del layout personalizzato in modo che sia intelligente su quali elementi si sta aggiornando.

Gli altri problemi riguardano le prestazioni di animazione in generale. Una cosa da tenere a mente è se c'è qualche tipo di compositing in corso - assicurati che le tue immagini siano opache. Un'altra cosa è se stai usando ombre sull'immagine, quelle possono essere costose da animare. Un modo per migliorare le prestazioni di animazione delle ombre è impostare il valore shadowPath quando l'immagine viene ridimensionata: se hai ombre, fammi sapere e inserisci del codice per farlo.

+0

Abbiamo già iterato su tutti gli elementi che sono all'interno del rect dato al layoutAttributesForElementsInRect. Ancora il sistema chiama il metodo layoutAttributesForItemAtIndexPath per tutte le celle all'esterno del rect.In caso di immagini, non usiamo alcuna ombra e sono già opachi. Un problema potrebbe essere la quantità di visualizzazioni visibili alla volta (circa 140). –

+0

Sarebbe utile se hai postato il codice. Un suggerimento, per scopi di debug, implementa la stessa vista di raccolta utilizzando l'UICollectionViewFlowLayout incorporato e fornisci parametri simili a quelli che stai utilizzando nella tua vista personalizzata. Attiva gli eventi che causano UICollectionViewFlowLayout alla riorganizzazione in modo significativo e controlla se le animazioni sono migliori. –

+0

FYI, Apple ha finalmente pubblicato un progetto di codice di esempio per CollectionViews. Sfortunatamente, è un'implementazione incredibilmente semplice - nessun layout personalizzato, che è il codice che ho davvero bisogno di vedere. –

0

Questo sembra essere causato dal tentativo di aggiungere celle a sezioni che hanno viste di intestazione ma nessuna cella già in esse.

Il messaggio di errore è enormemente inutile e sono state necessarie molte ore per rintracciarlo.

Problemi correlati