2

セルの高さと内容が異なる UICollectionView を使用して、ピンタレストのようなレイアウトのアプリの開発を開始しました。cellForItemAtIndexPath コールバックで使用されるテンプレート セル (ラベル + UIImageView) を定義しました。

その特定の関数 (cellForItemAtIndexPath) で、コンテンツ (UIImage) と UIImageView 要素のサイズを変更して、新しい画像の比率を尊重し、現在のセルの全幅を使用します。

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

FRGWaterfallCollectionViewCell *waterfallCell = [collectionView dequeueReusableCellWithReuseIdentifier:WaterfallCellIdentifier forIndexPath:indexPath];

[waterfallCell.layer setMasksToBounds:YES];
[waterfallCell.layer setCornerRadius:10.0];
[waterfallCell.layer setBorderWidth:1.0];
[waterfallCell.layer setBorderColor:[[UIColor darkGrayColor] CGColor]];
[waterfallCell.layer setNeedsDisplayOnBoundsChange:YES];

// some variables init
.....

// Get the new image
UIImage *image = [UIImage imageNamed: [NSString stringWithFormat: @"photo_%d.jpg", no_image]];

// Compute the image ratio
CGFloat largeur_img = image.size.width;
CGFloat hauteur_img = image.size.height;
CGFloat viewRatio = hauteur_img / largeur_img;

// Modify the UIImageView frame
CGRect cadre = waterfallCell.img_doc.frame;
<b>waterfallCell.img_doc.frame = CGRectMake(cadre.origin.x,cadre.origin.y,cadre.size.width, ceil(cadre.size.width * viewRatio));</b>

// We set the image of the UIImageView
<b>[waterfallCell.img_doc setImage:image];</b>

// Force to redraw the cell
<b>[waterfallCell setNeedsDisplay];</b>

return waterfallCell;

}

ただし、このセルは更新または再描画されません... UICollectionView を下にスクロールして上部に戻る場合を除いて、各セルの UIImageView は正しい形状になります。私はウェブで検索しましたが、setNeedsDisplayに関する多くの投稿を見ましたが、ここではCellがCALayerを使用しているように見えるので関係ありません..メインスレッドでリフレッシュすることは理解しましたが、起動する方法がわかりませんこの更新は、最初の表示、正しいサブ UIImageView を持つ正しいセルとその正しい寸法を取得するために行います。

ご協力いただきありがとうございます、

よろしく

ニコラス

4

2 に答える 2

0

私の意見では、比率に基づいてデキューする必要があります。これにより、すべてをまとめようとする多くの苦痛から解放されます。とにかく、あなたのアイテムには比率の制限セットがあります。さらに、既に使用されているセルのフレームを、ビューの大規模なリロードを開始せずに変更できるかどうかはわかりません。これは、CPU の点で非常にコストがかかります。

于 2013-10-30T16:25:54.517 に答える
0

問題はここにあります:

FRGWaterfallCollectionViewCell *waterfallCell = [collectionView dequeueReusableCellWithReuseIdentifier:WaterfallCellIdentifier forIndexPath:indexPath];

コントローラーを初めて開いたときは、デキューするセルがないため、waterfallCell は nil になります。(必要に応じて、これを確認するためにログを追加できます)。スクロールする場合にのみ、セルがデキューされます。そのため、スクロールする場合にのみ差異が表示されます。

カスタマイズされたコレクション ビュー セルを使用する場合、私は次のことを行います。

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *cellIdentifier = @"catalogOneRowCell";
    LACatalogOneRowCell *catalogCell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];

    if (catalogCell == nil) {
        catalogCell = [LACatalogOneRowCell getLACatalogOneRowCell];
    }

ここに LaCatalogOneRowCell.m があります

 + (LACatalogOneRowCell *)getLACatalogOneRowCell {
      NSArray *xib = [[NSBundle mainBundle] loadNibNamed:@"LACatalogOneRowCell" owner:nil options:nil];
      for (NSObject *obj in xib) {
          if ([obj isKindOfClass:[LACatalogOneRowCell class]]) {
              return (LACatalogOneRowCell *)obj;
          }
      }
     return nil;

}

そして非常に重要なことは、viewDidLoad で、セルのペン先を登録することです。

UINib *nib = [UINib nibWithNibName:@"LACatalogOneRowCell" bundle:nil];
[catalogCollectionView registerNib:nib forCellWithReuseIdentifier:@"catalogOneRowCell"];

また、cellforRow での割り当てはお勧めしません。

UIImage *image = [UIImage imageNamed:... 

*image = [[[UIImage alloc] initWithImage:.... ] autorelease]; と同じです。

cellForRow にオブジェクト、特に UIImage のようなオブジェクトを割り当てると、パフォーマンスが低下します。

于 2013-10-30T16:24:47.490 に答える