将子视图添加到 CollectionViewCell 一次(单元可重用性问题)

Adding subview to CollectionViewCell just once (cell reuseability issues)

我想在每个单元格的底部添加一个简单的渐变。在 cellForItemAtIndexPath: 我有代码:

CAGradientLayer *bottomFade = [CAGradientLayer layer];
bottomFade.name = @"Gradient";
bottomFade.frame = CGRectMake(0, cell.background.frame.size.height*0.8, cell.background.frame.size.width, cell.background.frame.size.height*0.2);
bottomFade.endPoint = CGPointMake(0.5, 1.0);
bottomFade.startPoint = CGPointMake(0.5, 0.0);
bottomFade.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithWhite:0.0 alpha:0.0f] CGColor], (id)[[UIColor colorWithWhite:0.0 alpha:0.2f] CGColor], nil];

[cell.background.layer addSublayer:bottomFade];

问题是在cell滚动的时候,sublayer一遍又一遍的添加,显然不是想要的效果

我知道如何处理 UITableView 的可重用性问题,但在使用 UICollectionView 时我应该怎么做?

我试图设置一个自定义单元格属性isConfigured,但是当我在cellForItemAtIndexPath:中检查它时,结果是只生成了两个单元格,然后它们在重复(老实说,我完全不知道为什么)。

你有什么建议来处理这样的问题?也许在单元格的子类中添加一些自定义代码会更好?

我已经解决了问题 ;).

在单元格的子类中:

-(void)layoutSubviews {

if (!self.isConfigured) {
    CAGradientLayer *bottomFade = [CAGradientLayer layer];
    bottomFade.name = @"Gradient";
    bottomFade.frame = CGRectMake(0, self.background.frame.size.height*0.8, self.background.frame.size.width, self.background.frame.size.height*0.2);
    bottomFade.endPoint = CGPointMake(0.5, 1.0);
    bottomFade.startPoint = CGPointMake(0.5, 0.0);
    bottomFade.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithWhite:0.0 alpha:0.0f] CGColor], (id)[[UIColor colorWithWhite:0.0 alpha:0.2f] CGColor], nil];

    [self.background.layer addSublayer:bottomFade];

    self.isConfigured = YES;
    }  

}

这样就可以了!但是,我还是很好奇 cellForItemAtIndexPath: 中的问题是否有简单的解决方法。

将只需要一次的代码放在 'awakeFromNib' 中,这样它就不会在其生命周期中被调用两次或三次

它会像这样显示:

- (void)awakeFromNib {
    [super awakeFromNib];

    CAGradientLayer *bottomFade = [CAGradientLayer layer];
    bottomFade.name = @"Gradient";
    bottomFade.frame = CGRectMake(0, self.background.frame.size.height*0.8, self.background.frame.size.width, self.background.frame.size.height*0.2);
    bottomFade.endPoint = CGPointMake(0.5, 1.0);
    bottomFade.startPoint = CGPointMake(0.5, 0.0);
    bottomFade.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithWhite:0.0 alpha:0.0f] CGColor], (id)[[UIColor colorWithWhite:0.0 alpha:0.2f] CGColor], nil];

    [self.background.layer addSublayer:bottomFade];
}

每次 UICollectionView 实例创建或重用 UICollectionViewCell 时都会调用 cellForItemAtIndexPath: 方法,这就是问题所在。

我不建议你像isConfigured一样使用属性,单元格应该保留一个BOOL变量,并且每次layoutSubviews都会检查属性调用,这是对内存和性能的浪费。

正如nferocious76所说,awakeFromNib:方法在其生命周期中只被调用一次,是这种情况的最佳解决方案。

顺便说一句,因为我无法评论,你应该在 layoutSubviews 方法的开头调用 [super layoutSubviews]