渐变蒙版在重用的原型单元中应用了多次

我有一个tableview,与一个客户UITableViewCell类 – 这是创build一个Storyboard / Builder中的原型单元格。

因为我的单元格与Storyboard原型相关联,所以我参考它(cellIdentifier与原型单元格上的ID匹配):

EventsListTableViewCell *cell = (EventsListTableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 

因此,单元格总是被初始化并准备就绪(我不能使用“if(cell == nil {…}”)

这很好,但是我想添加一个渐变图层到我的单元格,我正在做cellForRowAtIndex:

 gradientMask = [CAGradientLayer layer]; gradientMask.frame = cell.eventImage.layer.bounds; gradientMask.startPoint = CGPointMake(0.5, 0.2); gradientMask.endPoint = CGPointMake(0.5, 1.0); gradientMask.colors = [NSArray arrayWithObjects: (id)[[UIColor colorWithRed:0.0f green:0.0f blue:1.0f alpha:0.0f] CGColor], (id)[[UIColor colorWithRed:0.0f green:0.0f blue:1.0f alpha:1.0f] CGColor],nil]; [cell.eventImage.layer insertSublayer:gradientMask atIndex:0]; 

这里的问题是gradientMask被应用于单元格的每个重用,所以当我向下滚动时会变得越来越黑暗

我意识到我只需要应用这个gradientMask一次,当细胞第一次创build,但我不知道在哪里调用这个代码,因为我从来没有“初始化”细胞(这是由故事板处理)

我有这个单元格的自定义类,但它只包含属性和没有方法?

有多种方法可以实现这一点:

1-在UITableViewCell子类中的属性

在EventsListTableViewCell类中创build一个属性,它将保存对gradientMask的引用:

 @interface EventsListTableViewCell : UITableViewCell @property (weak, nonatomic) CAGradientLayer *gradientMask; @end 

然后在cellForRowAtIndexPath:方法中:

 if (!cell.gradientMask) { gradientMask = [CAGradientLayer layer]; gradientMask.frame = cell.eventImage.layer.bounds; gradientMask.startPoint = CGPointMake(0.5, 0.2); gradientMask.endPoint = CGPointMake(0.5, 1.0); gradientMask.colors = [NSArray arrayWithObjects: (id)[[UIColor colorWithRed:0.0f green:0.0f blue:1.0f alpha:0.0f] CGColor], (id)[[UIColor colorWithRed:0.0f green:0.0f blue:1.0f alpha:1.0f] CGColor],nil]; [cell.eventImage.layer insertSublayer:gradientMask atIndex:0]; cell.gradientMask = gradientMask; } 

这将确保gradientMask只被初始化一次。

2- CALayer 名称属性

这样,你不需要创build一个属性,所有的东西都可以在cellForRowAtIndexPath:方法中处理。

 BOOL gradientFound = NO; for (CALayer *layer in cell.eventImage.layer.sublayers) { if ([layer.name isEqualToString:@"gradientLayer"]) { gradientFound = YES; break; } } if (!gradientFound) { gradientMask = [CAGradientLayer layer]; gradientMask.frame = cell.eventImage.layer.bounds; gradientMask.name = @"gradientLayer"; //Set the name gradientMask.startPoint = CGPointMake(0.5, 0.2); gradientMask.endPoint = CGPointMake(0.5, 1.0); gradientMask.colors = [NSArray arrayWithObjects: (id)[[UIColor colorWithRed:0.0f green:0.0f blue:1.0f alpha:0.0f] CGColor], (id)[[UIColor colorWithRed:0.0f green:0.0f blue:1.0f alpha:1.0f] CGColor],nil]; [cell.eventImage.layer insertSublayer:gradientMask atIndex:0]; } 

3-在UITableViewCell子类中声明gradienLayer

这是最干净的方式,因为它也隔离了与其类中的单元相关的代码。 您可以在awakeFromNib方法中初始化单元格。

 @implementation EventsListTableViewCell { CAGradientLayer *gradientMask; } -(void)awakeFromNib { gradientMask = [CAGradientLayer layer]; gradientMask.frame = cell.eventImage.layer.bounds; gradientMask.startPoint = CGPointMake(0.5, 0.2); gradientMask.endPoint = CGPointMake(0.5, 1.0); gradientMask.colors = [NSArray arrayWithObjects: (id)[[UIColor colorWithRed:0.0f green:0.0f blue:1.0f alpha:0.0f] CGColor], (id)[[UIColor colorWithRed:0.0f green:0.0f blue:1.0f alpha:1.0f] CGColor],nil]; [self.eventImage.layer insertSublayer:gradientMask atIndex:0]; } @end 

由于您自己将此图层添加到故事板文件中,因此将在cellReuse循环中删除此图层。 你必须手动完成。
我通常为单元格创build一个子类,并覆盖prepareForReuse方法,在那里我删除了所有的自定义视图和图层。 这样一切都将顺利进行。
不要忘记只将你的子视图添加到单元格的contentView属性。