7

カスタム レイアウトで 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;
}    
4

2 に答える 2

4

コードを見なくても、layoutAttributesForElementsInRect メソッドがコレクション内のすべてのアイテムを繰り返し処理していると推測されます。つまり、他のメソッドが過剰に呼び出される原因となっているのです。layoutAttributesForElementsInRect は、画面上にあるものに関して、layoutAttributesForItemAtIndexPath を呼び出す必要がある項目について、ヒント (つまり、それが渡す CGRect) を提供します。

したがって、これはパフォーマンスの問題の一部である可能性があります。つまり、カスタム レイアウトを調整して、更新するアイテムをスマートにします。

その他の問題は、一般的なアニメーションのパフォーマンスに関連しています。注意すべきことの 1 つは、なんらかの合成が行われている場合です。画像が不透明であることを確認してください。もう 1 つの問題は、画像に影を使用している場合、アニメーション化にコストがかかる可能性があることです。影のアニメーション パフォーマンスを向上させる 1 つの方法は、画像のサイズを変更するときに shadowPath 値を設定することです。影がある場合は、それを行うためのコードをお知らせください。

于 2012-09-24T23:03:39.053 に答える
0

これは、ヘッダー ビューはあるがセルがまだ含まれていないセクションにセルを追加しようとしたことが原因のようです。

エラーメッセージは非常に役に立たず、追跡するのに数時間かかりました.

于 2013-01-15T23:59:23.670 に答える