【问题标题】:UICollectionViewCell : Reused Cell with UIImageView item not refreshed after image and size changesUICollectionViewCell :图像和大小更改后未刷新 UIImageView 项目的重用单元格
【发布时间】:2013-11-10 08:40:20
【问题描述】:

我已经开始开发一个具有类似 pinterest 布局的应用程序,其中 UICollectionView 具有不同的单元格高度和内容。我已经定义了一个模板单元格(标签 + 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 的正确单元格。

感谢您的帮助,

问候

尼古拉斯

【问题讨论】:

  • 您是否尝试过重置自定义 UICollectionViewCell 的 prepareForReuse 方法中的参数?
  • 你有没有找到解决办法。我面临着完全相同的问题。

标签: ios objective-c uicollectionview uicollectionviewcell


【解决方案1】:

问题就在这里:

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 中,注册您的单元格的 nib:

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 这样的对象

【讨论】:

  • 感谢 Durican 的回复。但是,我在重用回调的瀑布单元初始化之后设置了一个断点,但我从未捕获到零值,也许它之前在 WaterfallViewCollection 上被过滤。当您说在该函数中使用 imageNamed 是一个坏主意时,您是对的,但它仅用于测试刷新;-)。我是否可以分配一个具有多个具有正确尺寸的 Cell 和 UIImageView 调整大小并影响到 cellForItemAtIndexPath 回调中的 WaterfallCell 的数组,以免每次都重新计算和刷新?
  • 是的,这是我尝试优化 tableview 或 collectionview 时的第一步
  • -dequeueReusableCellWithReuseIdentifier:forIndexPath: 不会返回 nil。它总是会从它自己的未使用单元缓存中返回一个新构建的单元或一个已经构建的单元。请注意,这与我们熟悉和喜爱的旧 UITableView 的行为不同。
【解决方案2】:

在我看来,您应该根据比率出队。这将使您免于尝试将所有内容放在一起的痛苦。无论发生什么情况,您的物品无论如何都会有一组限制的比率。另外,我不确定您是否可以在不启动大量重新加载视图的情况下更改已使用的单元格的框架,这在 CPU 方面会非常昂贵。

【讨论】:

  • 感谢 stviv,但正如您所说,这意味着每个比率值都有一个单元模板,并且由于所有图像都不同,因此该模型无法使用...正如我对 Durican 的回答,我正在寻找如何用我的所有单元格和正确大小的元素初始化一个 MutableArray 并将这些单元格影响到 cellForItemAtIndexPath 回调,但我不知道该怎么做以及 UICollectionView 将如何修改我的单元格的位置以在布局中组织它们。如果你知道任何样本来做这样的任务,我会很感兴趣。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多