Wir versuchen, eine UICollectionView mit einem benutzerdefinierten Layout einzurichten. Der Inhalt jeder CollectionViewCell wird ein Bild sein. Insgesamt werden mehrere tausend Bilder und etwa 140-150 zu einer bestimmten Zeit sichtbar sein. Bei einem Aktionsereignis werden möglicherweise alle Zellen in Position und Größe reorganisiert. Das Ziel besteht darin, alle Bewegungsereignisse zu animieren, die derzeit die performBatchUpdates-Methode verwenden. Dies verursacht eine große Verzögerung, bevor alles animiert wird.UICollectionView-Leistungsprobleme bei performBatchUpdates
Bisher haben wir herausgefunden, dass intern die Methode layoutAttributesForItemAtIndexPath für jede einzelne Zelle aufgerufen wird (mehrere tausend insgesamt). Darüber hinaus wird die Methode cellForItemAtIndexPath für mehr Zellen aufgerufen, als tatsächlich auf dem Bildschirm angezeigt werden können.
Gibt es Möglichkeiten, die Leistung der Animation zu verbessern?
Der Standard UICollectionViewFlowLayout kann die Art von Design nicht wirklich bieten wir in der App realisieren möchten. Hier einige unserer Code:
-(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;
}
Die layoutAttributesForElementsInRect iteriert über alle Elemente layoutAttributes für allthe Elemente innerhalb des rect Einstellung. Die for-Anweisung bricht auf der ersten Zelle ist über die Grenzen von der unteren rechten Ecke des rect definiert:
-(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;
}
Auf Layout-Änderungen die Ergebnisse sind so ziemlich das gleiche, egal, ob die Anzahl der Zellen definiert ist, in der LayoutAttributesForElementsInRect ist begrenzt oder nicht .. Entweder das System erhält die Layout-Attribute für alle Zellen in dort, wenn es nicht begrenzt ist oder es ruft die LayoutAttributesForElementAtIndexPath-Methode für alle fehlenden Zellen, wenn es begrenzt ist. Insgesamt werden die Attribute für jede einzelne Zelle irgendwie verwendet.
-(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;
}
Bitte senden Sie Ihren Code von Ihrem UICollectionViewLayout. –