2016-09-13 33 views
2

这是对我昨天提出的问题的补充。结果非常完美,但我想要修改。 Using drawRect to draw & animate two graphs. A background graph, and a foreground graph动画CAShapeLayer/CAGradientLayer

以下代码基于上述线程生成一个CABasicAnimation,它生成深蓝色的“三角形”。而不是深蓝色的纯色,我希望这是一个CAGradientLayer,带3档:红色/绿色/蓝色。

我尝试添加CAGradientLayer来配置渐变,然后使用addSubLayer将渐变添加到动画化的CAShapeLayer。我在下面发布的结果不会生成动画。颜色和形状保持不变。梯度看起来不错,只是需要为它动画出来:

enter image description here

import UIKit 
import QuartzCore 
import XCPlayground 

let view = UIView(frame: CGRect(x: 0, y: 0, width: 521, height: 40)) 
view.backgroundColor = UIColor.whiteColor() 
XCPlaygroundPage.currentPage.liveView = view 

let maskPath = UIBezierPath() 

maskPath.moveToPoint(CGPoint(x: 0, y: 30)) 
maskPath.addLineToPoint(CGPoint(x: 0, y: 25)) 
maskPath.addLineToPoint(CGPoint(x: 300, y: 10)) 
maskPath.addLineToPoint(CGPoint(x: 300, y: 30)) 
maskPath.closePath() 

let maskLayer = CAShapeLayer() 
maskLayer.path = maskPath.CGPath 
maskLayer.fillColor = UIColor.whiteColor().CGColor 

let rectToAnimateFrom = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 0, height: 40)) 
let rectToAnimateTo = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 97, height: 40)) 

let backgroundGray = CAShapeLayer() 
backgroundGray.path = maskPath.CGPath 
backgroundGray.fillColor = UIColor.grayColor().CGColor 

let foregroundGradient = CAShapeLayer() 
foregroundGradient.mask = maskLayer 
foregroundGradient.backgroundColor = UIColor.clearColor().CGColor 


let gradientLayer = CAGradientLayer() 
gradientLayer.startPoint = CGPointMake(0, 0) 
gradientLayer.endPoint = CGPointMake(1, 0) 
gradientLayer.frame = maskPath.bounds 

let colors = [UIColor.redColor().CGColor, UIColor.greenColor().CGColor, UIColor.blueColor().CGColor] 
gradientLayer.colors = colors 


foregroundGradient.addSublayer(gradientLayer) 


view.layer.addSublayer(backgroundGray) 
view.layer.addSublayer(foregroundGradient) 


let animation = CABasicAnimation(keyPath: "path") 
animation.fromValue = rectToAnimateFrom.CGPath 
animation.toValue = rectToAnimateTo.CGPath 
animation.duration = 2 
animation.removedOnCompletion = false 
animation.fillMode = kCAFillModeForwards 


foregroundGradient.addAnimation(animation, forKey: nil) 

我需要foregroundGradient对象,以便从左至右(与gradientLayer子!)。

如果您从上述代码中删除渐变,并将foregroundGradient保持为纯色,您将看到动画。

+0

你能告诉我你在这里面临什么问题吗? – CodeChanger

+0

@Dhanesh - 它在第3段中提到。梯度LOOKS完美。确切的尺寸和颜色(S),我需要它。但是动画不起作用。看看我发布的帖子。蓝色动画从左到右,灰色三角形是背景。除了使用我的渐变外,我在这里需要相同的结果。 – Joe

回答

2

我认为您必须在您的视图中使用您的mask,如下所述。

//Remove below line 
view.layer.addSublayer(backgroundGray) 

//Add your mask to view 
view.layer.mask = backgroundGray 

整体功能看起来像这样:

func getGradientView() { 
    let view = UIView(frame: CGRect(x: 0, y: 50, width: 521, height: 40)) 
    view.backgroundColor = UIColor.grayColor() 
    self.view.addSubview(view) 

    let maskPath = UIBezierPath() 

    maskPath.moveToPoint(CGPoint(x: 0, y: 30)) 
    maskPath.addLineToPoint(CGPoint(x: 0, y: 25)) 
    maskPath.addLineToPoint(CGPoint(x: 300, y: 10)) 
    maskPath.addLineToPoint(CGPoint(x: 300, y: 30)) 
    maskPath.closePath() 

    let maskLayer = CAShapeLayer() 
    maskLayer.path = maskPath.CGPath 
    maskLayer.fillColor = UIColor.whiteColor().CGColor 

    let rectToAnimateFrom = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 0, height: 40)) 
    let rectToAnimateTo = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 300, height: 40)) 

    let backgroundGray = CAShapeLayer() 
    backgroundGray.path = maskPath.CGPath 
    backgroundGray.fillColor = UIColor.grayColor().CGColor 

    let foregroundGradient = CAShapeLayer() 
    foregroundGradient.mask = maskLayer 
    foregroundGradient.backgroundColor = UIColor.clearColor().CGColor 


    let gradientLayer = CAGradientLayer() 
    gradientLayer.startPoint = CGPointMake(0, 0) 
    gradientLayer.endPoint = CGPointMake(1, 0) 
    gradientLayer.frame = maskPath.bounds 

    let colors = [UIColor.redColor().CGColor, UIColor.greenColor().CGColor, UIColor.blueColor().CGColor] 
    gradientLayer.colors = colors 

    foregroundGradient.addSublayer(gradientLayer) 

    //Remove below line 
    //view.layer.addSublayer(backgroundGray) 

    view.layer.addSublayer(foregroundGradient) 

    //Add you mask to view 
    view.layer.mask = backgroundGray 

    let animation = CABasicAnimation(keyPath: "path") 
    animation.fromValue = rectToAnimateFrom.CGPath 
    animation.toValue = rectToAnimateTo.CGPath 
    animation.duration = 1 
    animation.repeatCount = 1000 
    animation.removedOnCompletion = false 
    animation.fillMode = kCAFillModeForwards 


    maskLayer.addAnimation(animation, forKey: "fill animation") 
} 

让我知道,如果按你的例外工作。

+0

这个作品完美!谢谢!!! – Joe