-2

How to add a gradient in UIBezierPath, I have a draw path in my UITabbar but I am not able to add a gradient in draw path, I don't want to apply as UITababr background, I want to apply only in draw path.

below is my code

 private func addShape() {
        let shapeLayer = CAShapeLayer()
        shapeLayer.path = createPath()
        shapeLayer.lineWidth = 1.0
        if let oldShapeLayer = self.shapeLayer {
            tabBar.layer.replaceSublayer(oldShapeLayer, with: shapeLayer)
        } else {
            tabBar.layer.insertSublayer(shapeLayer, at: 0)
        }
        self.shapeLayer = shapeLayer

    }



    func createPath() -> CGPath {



        let height: CGFloat = 33

        let path = UIBezierPath()

        let centerWidth = self.view.frame.width / 2



        path.move(to: CGPoint(x: 42, y: 0)) // start top left

        path.addLine(to: CGPoint(x: (centerWidth - height * 1.5), y: 0)) // the beginning of the trough



        path.addCurve(to: CGPoint(x: centerWidth, y: height),

                      controlPoint1: CGPoint(x: (centerWidth - 30), y: 0), controlPoint2: CGPoint(x: centerWidth - 35, y: height))

        // second curve up

        path.addCurve(to: CGPoint(x: (centerWidth + height * 2), y: 0),

                      controlPoint1: CGPoint(x: centerWidth + 35, y: height), controlPoint2: CGPoint(x: (centerWidth + 30), y: 0))



        // complete the rect

        path.addLine(to: CGPoint(x: self.view.frame.width-42, y: 0))





        // Added curve for right side

        path.addCurve(to: CGPoint(x: self.tabBar.frame.width-10, y: 25),

                      controlPoint1: CGPoint(x: self.tabBar.frame.width-20, y: 5),

                      controlPoint2: CGPoint(x: self.tabBar.frame.width-10, y: 15))

        path.addCurve(to: CGPoint(x: self.tabBar.frame.width - 50, y: self.tabBar.frame.height-10),

                      controlPoint1: CGPoint(x: self.tabBar.frame.width - 10, y: self.tabBar.frame.height-30),

                      controlPoint2: CGPoint(x: self.tabBar.frame.width - 10, y: self.tabBar.frame.height-10))

        path.addLine(to: CGPoint(x: 50, y: self.tabBar.frame.height - 10))

        // Added curve for left side

        path.addCurve(to: CGPoint(x: 10, y: 25),

                      controlPoint1: CGPoint(x: 10, y: self.tabBar.frame.height-10),

                      controlPoint2: CGPoint(x: 10, y: self.tabBar.frame.height-30 ))

        path.addCurve(to: CGPoint(x: 42, y: 0),

                      controlPoint1: CGPoint(x: 10, y: 15),

                      controlPoint2: CGPoint(x: 20, y: 5))

        path.close()



        return path.cgPath

    }
Darshan
  • 2,272
  • 3
  • 31
  • 43

1 Answers1

0

You can use a CAGradientLayer to get the gradient effect, and use the CAShapeLayer as a mask.

e.g.:

Objective C

- (void)viewDidLoad
{
    [super viewDidLoad];

    int radius = 100;

    CAShapeLayer * tabBar = [CAShapeLayer layer];    
    tabBar.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 50) radius:radius startAngle:60.0 endAngle:0.0 clockwise:YES].CGPath;

    tabbar.position = CGPointMake(CGRectGetMidX(self.view.frame)-radius,
                               CGRectGetMidY(self.view.frame)-radius);

    tabBar.fillColor = [UIColor clearColor].CGColor;
    tabBar.strokeColor = [UIColor purpleColor].CGColor;
    tabBar.lineWidth = 15; 
    CABasicAnimation *drawAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    drawAnimation.duration            = 5.0; // "animate over 10 seconds or so.."
    drawAnimation.repeatCount         = 1.0;  // Animate only once..
    drawAnimation.removedOnCompletion = NO;   // Remain stroked after the animation..
    drawAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
    drawAnimation.toValue   = [NSNumber numberWithFloat:10.0f];
    drawAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
    [tabBar addAnimation:drawAnimation forKey:@"drawCircleAnimation"];

    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    gradientLayer.frame = self.view.frame;
    gradientLayer.colors = @[(__bridge id)[UIColor redColor].CGColor,(__bridge id)[UIColor blueColor].CGColor ];
    gradientLayer.startPoint = CGPointMake(0,0.5);
    gradientLayer.endPoint = CGPointMake(1,0.5);

    [self.view.layer addSublayer:gradientLayer];
     //Using tabBar as a mask instead of adding it as a sublayer.
     //[self.view.layer addSublayer:tabBar]; 
     gradientLayer.mask = tabBar;


}

Swift

private func addGradientLayer(to layer: CALayer, path: UIBezierPath) {
    // ------- 1 --------
    let gradientMask = CAShapeLayer()
    gradientMask.contentsScale = UIScreen.main.scale
    // ------- 2 --------
    gradientMask.strokeColor = UIColor.white.cgColor
    gradientMask.path = path.cgPath

    // ------- 3 --------
    let gradientLayer = CAGradientLayer()
    // ------- 4 --------
    gradientLayer.mask = gradientMask
    gradientLayer.frame = layer.frame
    gradientLayer.contentsScale = UIScreen.main.scale
    // ------- 5 --------
    gradientLayer.colors = [UIColor.gray.cgColor, UIColor.green.cgColor]
    // ------- 6 --------
    layer.addSublayer(gradientLayer)
}
Jawad Ali
  • 13,556
  • 3
  • 32
  • 49