horizontal CAGradientLayer in iOS 7.0

Perry picture Perry · Oct 28, 2013 · Viewed 16.6k times · Source

Inside my application I use a CAGradientLayer to set the background of my cell, in this way:

retValue = [tableView dequeueReusableCellWithIdentifier:@"Cells" forIndexPath:indexPath];
UIView *bgColorView = [[UIView alloc] init];
bgColorView.backgroundColor = [UIColor blueColor];
bgColorView.layer.masksToBounds = YES;
id startColor = (id)[[UIColor colorWithWhite:0.75 alpha:1] CGColor];
id endColor = (id)[[UIColor blueColor] CGColor];
CAGradientLayer* gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = retValue.contentView.bounds;
gradientLayer.colors = @[startColor,startColor,endColor,endColor];
gradientLayer.locations = @[[NSNumber numberWithFloat:0],
    [NSNumber numberWithFloat:0.95],
    [NSNumber numberWithFloat:0.95],
    [NSNumber numberWithFloat:1]];
[gradientLayer setStartPoint:CGPointMake(0,0.5)];
[gradientLayer setEndPoint:CGPointMake(1,0.5)];
[bgColorView.layer addSublayer:gradientLayer];
retValue.selectedBackgroundView = bgColorView;

(this code is inside - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath)

It works fine on iOS 6 but does not work on iOS 7, in the new iOS the gradient is always vertical (startPoint and endPoint are ignored)

does anyone encountered in the same issue?

Thanks,

Perry

Answer

Gord Larson picture Gord Larson · Mar 9, 2014

This questions is fairly old, but I came across it, so others likely will as well. The following code will produce a horizontal gradient running on an iPhone simulator with version 7.0.3

+ (void)drawGradientOverContainer:(UIView *)container
{
    UIColor *transBgColor = [UIColor colorWithWhite:1.0 alpha:0.0];
    UIColor *black = [UIColor blackColor];
    CAGradientLayer *maskLayer = [CAGradientLayer layer];
    maskLayer.opacity = 0.8;
    maskLayer.colors = [NSArray arrayWithObjects:(id)black.CGColor, 
    (id)transBgColor.CGColor, (id)transBgColor.CGColor, (id)black.CGColor, nil];

    // Hoizontal - commenting these two lines will make the gradient veritcal
    maskLayer.startPoint = CGPointMake(0.0, 0.5);
    maskLayer.endPoint = CGPointMake(1.0, 0.5);

    NSNumber *gradTopStart = [NSNumber numberWithFloat:0.0];
    NSNumber *gradTopEnd = [NSNumber numberWithFloat:0.4];
    NSNumber *gradBottomStart = [NSNumber numberWithFloat:0.6];
    NSNumber *gradBottomEnd = [NSNumber numberWithFloat:1.0];
    maskLayer.locations = @[gradTopStart, gradTopEnd, gradBottomStart, gradBottomEnd];

    maskLayer.bounds = container.bounds;
    maskLayer.anchorPoint = CGPointZero;
    [container.layer addSublayer:maskLayer];
}

I'm not sure why your code doesn't work, but I get odd behaviour if I do not set the anchor point - the gradient is still horizontal though. Maybe it has something to do with it being a cell background view - you could try applying the gradient to the underlying table.