Search code examples
iosobjective-ccore-animationcagradientlayer

Gradient Layer over ImageView reuse


Within my 'cellForRowAtIndexPath' I have the following code to populate the image (async) and apply a custom gradient

This worked fine, until I added a custom colour per cell. What it's currently doing is recycling the previous colour rather than applying a new one - this is presumably due to the following line which will skip the gradient code once applied to each cell:

if(!cell.gradientMask){

However, if I comment this out, the colours work but the gradient on each cell will stack up as a new layer is added each time (see existing issue)

I presume I need to remove the gradientLayer on each iteration, is that the best approach or perhaps I need to subclass the UIImageView?

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);


   /* THIS COLOUR CHANGES FOR EACH CELL */
   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;
}

Solution

  • You need to set the colors outside the block which creates the gradientMask:

    if (!cell.gradientMask) {  //Operations that need to be carried out only ONCE are put inside this block
        gradientMask = [CAGradientLayer layer];
        gradientMask.frame = cell.eventImage.layer.bounds;
    
        gradientMask.startPoint = CGPointMake(0.5, 0.2);
       gradientMask.endPoint = CGPointMake(0.5, 1.0);
    
        [cell.eventImage.layer insertSublayer:gradientMask atIndex:0];
        cell.gradientMask = gradientMask;
    }
    
    //Operations that need to be carried out again and again are outside the block
    if (condition1)
    {
        cell.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];
    }
    else
    {
        cell.gradientMask.colors = [NSArray arrayWithObjects:
                       (id)[[UIColor colorWithRed:0.0f green:1.0f blue:0.0f alpha:0.0f] CGColor],
    
                       (id)[[UIColor colorWithRed:0.0f green:1.0f blue:0.0f alpha:1.0f] CGColor],nil];
    }