6

中にUICollectionView30枚UICollectionViewCell入っています。現在画面に表示されている 8 つのセルがあり、残りはほとんど表示されていません。表示されているすべてのセルからフレーム値を取得できます。

私の質問は、目に見えないセルを含むすべてのセルからフレーム値を取得するにはどうすればよいかです。

これは私のコードです。

// some code before

for (int i = 0; i < [collectionView numberOfItemsInSection:0]; i++) {
    cell = [collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]];
    if (!cell) {
        [collectionView performBatchUpdates:^{
            [collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0] atScrollPosition:UICollectionViewScrollPositionTop animated:NO];
            [collectionView reloadData];
        } completion:^(BOOL finished) {
            cell = [collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]];
            NSLog(@"- after batch update %d %@", i, NSStringFromCGRect(cell.frame));
        }];
    }
    NSLog(@"- %d %@", i, NSStringFromCGRect(cell.frame));
}

// another long code

結果は、最初の 8 セルの正しいフレームを取得できました。次のセル (見えないセル) のフレームが間違っています。

これはログです:

2013-07-08 16:38:57.904 My App[71245:c07] - 0 {{2, 2}, {217, 326}}
2013-07-08 16:38:57.905 My App[71245:c07] - 1 {{231, 2}, {217, 326}}
2013-07-08 16:38:57.906 My App[71245:c07] - 2 {{460, 2}, {217, 326}}
2013-07-08 16:38:57.906 My App[71245:c07] - 3 {{689, 2}, {217, 315}}
2013-07-08 16:38:57.907 My App[71245:c07] - 4 {{689, 340}, {217, 326}}
2013-07-08 16:38:57.909 My App[71245:c07] - 5 {{2, 340}, {217, 329}}
2013-07-08 16:38:57.909 My App[71245:c07] - 6 {{231, 340}, {217, 315}}
2013-07-08 16:38:57.910 My App[71245:c07] - 7 {{460, 340}, {217, 286}}
2013-07-08 16:38:57.910 My App[71245:c07] - 8 {{0, 0}, {0, 0}}
2013-07-08 16:38:57.911 My App[71245:c07] - 9 {{0, 0}, {0, 0}}
2013-07-08 16:38:57.911 My App[71245:c07] - 10 {{0, 0}, {0, 0}}
2013-07-08 16:38:57.912 My App[71245:c07] - 11 {{0, 0}, {0, 0}}
2013-07-08 16:38:57.912 My App[71245:c07] - 12 {{0, 0}, {0, 0}}
2013-07-08 16:38:57.913 My App[71245:c07] - 13 {{0, 0}, {0, 0}}
2013-07-08 16:38:57.913 My App[71245:c07] - 14 {{0, 0}, {0, 0}}
2013-07-08 16:38:57.904 My App[71245:c07] - after batch update 8 {{689, 640}, {217, 326}}
2013-07-08 16:38:57.905 My App[71245:c07] - after batch update 9 {{689, 640}, {217, 326}}
2013-07-08 16:38:57.906 My App[71245:c07] - after batch update 10 {{2, 640}, {217, 326}}
2013-07-08 16:38:57.906 My App[71245:c07] - after batch update 11 {{231, 640}, {217, 315}}
2013-07-08 16:38:57.907 My App[71245:c07] - after batch update 12 {{460, 920}, {217, 326}}
2013-07-08 16:38:57.909 My App[71245:c07] - after batch update 13 {{2, 920}, {217, 329}}
2013-07-08 16:38:57.909 My App[71245:c07] - after batch update 14 {{231, 920}, {217, 315}}
4

4 に答える 4

16

フレームを取得するためにセルを表示する必要はありません。コレクション ビューはフレーム (およびその他のレイアウト属性) を で管理するcollectionViewLayoutため、そこからフレームを取得できます。

NSInteger numberOfCells = [self.collectionView numberOfItemsInSection:0];
UICollectionViewLayout *layout = self.collectionView.collectionViewLayout;
for (NSInteger i = 0; i < numberOfCells; i++) {
    UICollectionViewLayoutAttributes *layoutAttributes = [layout layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]];
    CGRect cellFrame = layoutAttributes.frame;
    NSLog(@"%i - %@", i, NSStringFromCGRect(cellFrame));
}
于 2013-07-08T10:14:03.360 に答える
1

セルが表示されている四角形を超えて拡張されたコレクション ビューの画像をキャプチャする必要があるときに、同様の問題に直面していました。すべてのセルのレイアウト情報以上の情報が必要でした。コレクション ビュー全体を実際に描画するシステムが必要でした。scrollToItemAtIndexPath画像をキャプチャする前にプログラム全体をスイープして全体を強制的に描画する方法を使用しようとしましたが、うまくいきませんでした。

解決策は、イメージ キャプチャ メソッド内で、コレクション ビュー フレームをコンテンツ全体のサイズと一致するように設定し、invalidate layoutを呼び出すことでした。画像をキャプチャした後、コレクション ビューを元の UI サイズに復元したところ、完全に機能しました。

- (UIImage *)getImageOfEntireCollectionView {

     // Store original CV frame and get content size
     CGPoint refCVOrigin = self.collectionView.frame.origin;
     CGSize refCVSize = self.collectionView.frame.size;
     CGSize contentSize = [self.collectionView.collectionViewLayout collectionViewContentSize];

     // expand CV size to match content size and redraw it
     self.collectionView.frame = CGRectMake(0, 0, contentSize.width, contentSize.height); 
     [self.layout invalidateLayout];
     [self.collectionView reloadData];

     // capture image of CV
     UIGraphicsBeginImageContext(self.collectionView.bounds.size);
     [self.collectionView.layer renderInContext:UIGraphicsGetCurrentContext()];
     UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext();
     UIGraphicsEndImageContext();

     // restore original CV frame
     self.collectionView.frame = CGRectMake(refCVOrigin.x, refCVOrigin.y, refCVSize.width, refCVSize.height);

     return screenshot;
}
于 2014-11-12T02:40:39.080 に答える
0

UICollection ビューは、コレクション内のすべての要素のセルを保存しません。見えるものに限ります。スクロールすると、すでに表示されていないものを再利用できます。したがって、存在しないセルのプロパティを取得することはできません。

MVC では、データと、データの一部を表す可視セルのみを操作する必要があります。したがって、あなたがやろうとしていることは概念的に間違っています。

于 2013-07-08T10:03:44.247 に答える