カスタム レイアウトで UICollectionView を設定しようとしています。各 CollectionViewCell のコンテンツは画像になります。全部で数千の画像があり、一度に約 140 ~ 150 の画像が表示されます。アクション イベントでは、すべてのセルの位置とサイズが再編成される可能性があります。目標は、現在 performBatchUpdates メソッドを使用してすべての移動イベントをアニメーション化することです。これにより、すべてがアニメーション化されるまでに大きな遅延時間が発生します。
ここまでで、メソッド layoutAttributesForItemAtIndexPath がすべての単一セル (合計で数千) に対して内部的に呼び出されることがわかりました。さらに、cellForItemAtIndexPath メソッドは、実際に画面に表示できるよりも多くのセルに対して呼び出されます。
アニメーションのパフォーマンスを向上させる可能性はありますか?
デフォルトの UICollectionViewFlowLayout では、アプリで実現したい種類のデザインを実際に提供することはできません。コードの一部を次に示します。
-(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;
}
layoutAttributesForElementsInRect は、rect 内のすべての要素の layoutAttributes を設定するすべての要素を反復処理します。for ステートメントは、最初のセルが四角形の右下隅によって定義された境界線を超えたところで中断します。
-(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;
}
レイアウトの変更では、layoutAttributesForElementsInRect で定義されているセルの数が制限されているかどうかに関係なく、結果はほとんど同じです。制限されていない場合、システムはそこにあるすべてのセルのレイアウト属性を取得するか、制限されている場合は、欠落しているすべてのセルの layoutAttributesForElementAtIndexPath メソッド。全体として、すべての単一セルの属性が何らかの形で使用されています。
-(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;
}