7

セルをグリッド形式でレイアウトするカスタム レイアウトで UICollectionView を使用しています。50 行と 50 列をはるかに超える場合があります。スクロールは、垂直方向と水平方向の両方で発生します。現在、すべてのレイアウト設定をprepareLayout配列に保存しています。

- (void)prepareLayout {

     NSMutableArray *newLayoutInfo = [[NSMutableArray alloc] init];
     NSMutableArray *newLinearLayoutInfor = [[NSMutableArray alloc] init];

     NSInteger sectionCount = [self.collectionView numberOfSections];
     NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];

     self.heightForRows = [delegate collectionViewHeightForAllRows];

     self.totalWidthsForRows = [[NSMutableArray alloc] init];

     for (int i = 0; i < sectionCount; i++) {
       [self.totalWidthsForRows addObject:[NSNumber numberWithInt:0]];
     }
     for (NSInteger section = 0; section < sectionCount; section++) {
       NSMutableArray *cellLayoutInfo = [[NSMutableArray alloc] init];


       NSInteger itemCount = [self.collectionView numberOfItemsInSection:section];

     for (NSInteger item = 0; item < itemCount; item++) {
        indexPath = [NSIndexPath indexPathForItem:item inSection:section];

        UICollectionViewLayoutAttributes *itemAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
        itemAttributes.frame = [self frameForCellAtIndexPath:indexPath];

        [cellLayoutInfo addObject:itemAttributes];
        [newLinearLayoutInfor addObject:itemAttributes];
    }
    [newLayoutInfo addObject:cellLayoutInfo];
}
self.layoutInfo = newLayoutInfo;
self.linearLayoutInfo = newLinearLayoutInfor;
}

それからlayoutAttributesForElementsInRect私は持っています:

- (NSArray*)layoutAttributesForElementsInRect:(CGRect)rect {
NSArray *rows = [self.linearLayoutInfo filteredArrayUsingPredicate:[NSPredicate    predicateWithBlock:^BOOL(UICollectionViewLayoutAttributes *evaluatedObject, NSDictionary *bindings) {
    return CGRectIntersectsRect(rect, [evaluatedObject frame]);
}]];

これは問題なく動作しますが、50 列と 50 行を超えるとラグが発生し、不安定になります。私が今抱えている問題は、設定する必要があるということです

-(BOOL)shouldInvalidateLayoutForBoundsChange {
       return YES;
} 

これにより、境界が変更されるたびにレイアウト全体が準備されます。これは、言うまでもなく、パフォーマンスに大きな影響を与え、ほとんどスクロールできません。セルは不透明な背景のテキストだけで構成されているため、問題はありません。

私はこれを正しく行っていないと確信しており、より良い方法があるに違いありません。事前に助けてくれてありがとう。

4

3 に答える 3

5
-(BOOL)shouldInvalidateLayoutForBoundsChange {
       return YES;
} 

スクロールするたびにレイアウトが実行されますprepareLayout()。つまり、準備中の負荷の高いコンピューティングは遅延につながるため、これを解決するための 1 つの方法は、実際に時間がかかっていることを確認することです。1つの可能性は中身です

for (NSInteger section = 0; section < sectionCount; section++)
{
   // generate attributes ...
}

レイアウトの属性を生成するため。スクロールするたびに、この一般化が再実行されるたびに、スクロールへの影響がびくびくとぎこちないように見えます。したがって、この問題を解決するため、または少なくともこれが実際の問題ではないことを整理するために、レイアウトの準備が必要な状況を表す isScrollingなど、このレイアウト アルゴリズムにフラグを設定することをお勧めします。prepareLayout()フラグをチェックするたびに 、それがYESの場合 、最初にレイアウトが初期化されて以来、すべての属性を再生成するために for ループを実行する必要がないことがわかります。

于 2013-03-24T04:05:08.833 に答える
0

はい、分かりました。3 つのコレクション ビューを作成することをお勧めします。1 つは列ヘッダー用 (各セルは列ヘッダー)、もう 1 つは行リーダー用 (各セル = 1 行リーダー)、およびセル用の 1 つのコレクション ビューです。次に、任意のコレクション ビューのスクロール位置がユーザーによって変更されたときに、他の 2 つのコレクション ビューのスクロール位置を適切に更新します。

ここに画像の説明を入力

于 2013-03-02T21:42:55.920 に答える