2

我已经开始使用具有不同单元格高度和内容的 UICollectionView 开发具有类似 pinterest 布局的应用程序。我已经定义了一个模板单元格(标签 + UIImageView),它通过 cellForItemAtIndexPath 回调来使用。

在该特定函数 (cellForItemAtIndexPath) 中,我正在修改 UIImageView 元素的内容 (UIImage) 和大小,以尊重新图像的比例并使用当前单元格的整个宽度。

- (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

In my opinion, you should dequeue based on ratio. This will save you from a lot of pain trying to put everything together. Whatever happens your items will have a limit set of ratios anyway. Plus I'm not sure you can change the frame of a cell that's already been used without kicking off a large reload of the view which would be quite costly in terms of CPU.

于 2013-10-30T16:25:54.517 回答
0

问题就在这里:

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

在您第一次打开控制器时,没有要出列的单元格,因此瀑布单元格将为 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:... 

和 UIImage 一样 *image = [[[UIImage alloc] initWithImage:.... ] autorelease];

在 cellForRow 中分配对象对性能不利,尤其是像 UIImage 这样的对象

于 2013-10-30T16:24:47.490 回答