Estamos tratando de configurar un UICollectionView con un diseño personalizado. El contenido de cada CollectionViewCell será una imagen. Sobre todo habrá varios miles de imágenes y aproximadamente 140-150 siendo visibles en un momento determinado. En un evento de acción, potencialmente todas las celdas se reorganizarán en posición y tamaño. El objetivo es animar todos los eventos en movimiento que actualmente usan el método performBatchUpdates. Esto provoca un gran retraso antes de que todo se anima.UICollectionView Problemas de rendimiento en performBatchUpdates
Hasta aquí hemos descubierto que internamente se llama al método layoutAttributesForItemAtIndexPath para cada celda (varios miles en total). Además, se llama al método cellForItemAtIndexPath para obtener más celdas de las que realmente se pueden mostrar en la pantalla.
¿Hay alguna posibilidad de mejorar el rendimiento de la animación?
El valor predeterminado UICollectionViewFlowLayout en realidad no puede ofrecer el tipo de diseño que queremos realizar en la aplicación. He aquí algunos de nuestro código:
-(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;
}
Los itera layoutAttributesForElementsInRect más de todos los elementos de ajuste para layoutAttributes allthe elementos dentro del rect. Las pausas para-declaración sobre la primera celda que se está más allá de las fronteras definidas por la esquina inferior derecha de la rect:
-(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;
}
El diseño cambia los resultados son más o menos los mismos sin importar si se está definiendo el número de células en layoutAttributesForElementsInRect está limitado o no ... O el sistema obtiene los atributos de diseño para todas las celdas allí si no está limitado o llama al método layoutAttributesForElementAtIndexPath para todas las celdas que faltan si está limitado. En general, los atributos para cada celda se utilizan de alguna manera.
-(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;
}
Publica el código de tu UICollectionViewLayout. –