25

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

Nirav Gadhiya
  • 6,342
  • 2
  • 37
  • 76
Perry
  • 1,113
  • 2
  • 10
  • 22

3 Answers3

45

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.

Gord Larson
  • 566
  • 6
  • 4
  • 5
    Note that `[UIColor clearColor]` creates a weird gray nuance. As this answer does, use the `[UIColor colorWithWhite:1.0 alpha:0.0]` instead. This will give you a transparent gradient. – ThomasCle Jun 12 '15 at 08:49
15

In Swift 4 I've implemented a nice working extension:

extension UIView {

    enum GradientColorDirection {
        case vertical
        case horizontal
    }

    func showGradientColors(_ colors: [UIColor], opacity: Float = 1, direction: GradientColorDirection = .vertical) {
        let gradientLayer = CAGradientLayer()
        gradientLayer.opacity = opacity
        gradientLayer.colors = colors.map { $0.cgColor }

        if case .horizontal = direction {
            gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0)
            gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.0)
        }

        gradientLayer.bounds = self.bounds
        gradientLayer.anchorPoint = CGPoint.zero
        self.layer.addSublayer(gradientLayer)
    }

}
Luca Davanzo
  • 21,000
  • 15
  • 120
  • 146
4

Just came across it now, 3 years after. Thank you Gord for this solution. Here it is in Swift 3.0:

func drawGradientOver(container: UIView) {
    let transBgColor = UIColor.clear
    let black = UIColor.black
    let maskLayer = CAGradientLayer()
    maskLayer.opacity = 0.8
    maskLayer.colors = [black.cgColor, transBgColor.cgColor, transBgColor.cgColor, black.cgColor]

    // Hoizontal - commenting these two lines will make the gradient veritcal
    maskLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
    maskLayer.endPoint = CGPoint(x: 1.0, y: 0.5)

    let gradTopStart = NSNumber(value: 0.0)
    let gradTopEnd = NSNumber(value: 0.4)
    let gradBottomStart = NSNumber(value: 0.6)
    let gradBottomEnd = NSNumber(value: 1.0)
    maskLayer.locations = [gradTopStart, gradTopEnd, gradBottomStart, gradBottomEnd]

    maskLayer.bounds = container.bounds
    maskLayer.anchorPoint = CGPoint.zero
    container.layer.addSublayer(maskLayer)
}
Rici
  • 1,014
  • 2
  • 12
  • 21