Ios 如何在UIBezierPath上设置填充颜色更改的动画?
形状一开始是正确填充的,但我不知道如何更改填充颜色,或者更好的是,如何在Ios 如何在UIBezierPath上设置填充颜色更改的动画?,ios,swift,Ios,Swift,形状一开始是正确填充的,但我不知道如何更改填充颜色,或者更好的是,如何在UIBezierPath上设置填充颜色更改的动画。就像更改UIView的背景色一样,我正在寻找 var fillColor = UIColor() func changeBackgroundColor() { let animcolor = CABasicAnimation(keyPath: "fillColor") animcolor.fromValue = UIColor.greenColor()
UIBezierPath
上设置填充颜色更改的动画。就像更改UIView的背景色一样,我正在寻找
var fillColor = UIColor()
func changeBackgroundColor() {
let animcolor = CABasicAnimation(keyPath: "fillColor")
animcolor.fromValue = UIColor.greenColor()
animcolor.toValue = UIColor.orangeColor()
animcolor.duration = 1.0;
animcolor.repeatCount = 0;
animcolor.autoreverses = true
shapeLayer.addAnimation(animcolor, forKey: "fillColor")
}
var fillColor = UIColor()
let clipPath = UIBezierPath()
let shapeLayer = CAShapeLayer()
override func drawRect(rect: CGRect) {
clipPath.moveToPoint(CGPointMake(self.bounds.minX + 7.65, self.bounds.minY - 0.25))
clipPath.addCurveToPoint(CGPointMake(self.bounds.minX + 7.65, self.bounds.minY + 36.1), controlPoint1: CGPointMake(self.bounds.minX - 2.38, self.bounds.minY + 9.79), controlPoint2: CGPointMake(self.bounds.minX - 2.38, self.bounds.minY + 26.06))
clipPath.addCurveToPoint(CGPointMake(self.bounds.minX + 43.99, self.bounds.minY + 36.1), controlPoint1: CGPointMake(self.bounds.minX + 17.69, self.bounds.minY + 46.13), controlPoint2: CGPointMake(self.bounds.minX + 33.96, self.bounds.minY + 46.13))
clipPath.addLineToPoint(CGPointMake(self.bounds.minX + 43.99, self.bounds.minY + 36.1))
clipPath.addLineToPoint(CGPointMake(self.bounds.minX + 44.01, self.bounds.minY + 0.19))
clipPath.addLineToPoint(CGPointMake(self.bounds.minX + 7.58, self.bounds.minY + 0.19))
clipPath.usesEvenOddFillRule = true
fillColor = userColor
}
clipPath.addClip()
fillColor.setFill()
clipPath.fill()
shapeLayer.path = clipPath.CGPath
self.layer.mask = shapeLayer
就像更改UIView的背景色一样,我正在寻找
var fillColor = UIColor()
func changeBackgroundColor() {
let animcolor = CABasicAnimation(keyPath: "fillColor")
animcolor.fromValue = UIColor.greenColor()
animcolor.toValue = UIColor.orangeColor()
animcolor.duration = 1.0;
animcolor.repeatCount = 0;
animcolor.autoreverses = true
shapeLayer.addAnimation(animcolor, forKey: "fillColor")
}
var fillColor = UIColor()
let clipPath = UIBezierPath()
let shapeLayer = CAShapeLayer()
override func drawRect(rect: CGRect) {
clipPath.moveToPoint(CGPointMake(self.bounds.minX + 7.65, self.bounds.minY - 0.25))
clipPath.addCurveToPoint(CGPointMake(self.bounds.minX + 7.65, self.bounds.minY + 36.1), controlPoint1: CGPointMake(self.bounds.minX - 2.38, self.bounds.minY + 9.79), controlPoint2: CGPointMake(self.bounds.minX - 2.38, self.bounds.minY + 26.06))
clipPath.addCurveToPoint(CGPointMake(self.bounds.minX + 43.99, self.bounds.minY + 36.1), controlPoint1: CGPointMake(self.bounds.minX + 17.69, self.bounds.minY + 46.13), controlPoint2: CGPointMake(self.bounds.minX + 33.96, self.bounds.minY + 46.13))
clipPath.addLineToPoint(CGPointMake(self.bounds.minX + 43.99, self.bounds.minY + 36.1))
clipPath.addLineToPoint(CGPointMake(self.bounds.minX + 44.01, self.bounds.minY + 0.19))
clipPath.addLineToPoint(CGPointMake(self.bounds.minX + 7.58, self.bounds.minY + 0.19))
clipPath.usesEvenOddFillRule = true
fillColor = userColor
}
clipPath.addClip()
fillColor.setFill()
clipPath.fill()
shapeLayer.path = clipPath.CGPath
self.layer.mask = shapeLayer
但你为什么不能做到呢?您已经将视图遮罩到您的路径,因此设置背景颜色动画将获得您想要的确切效果。只需去掉核心图形路径填充,并根据需要删除drawRect
覆盖即可
如果你真的需要使用<代码> DRACORT 并激活该颜色,你可以考虑将你的<代码> uiVIEW/CODE分割成两个<代码> uiVIEW/COD>——一个绘制背景层(你可以动画),一个绘制自定义图。或者,您可以设置一个
CADisplayLink
,以使用中间背景色重新绘制每个帧的视图,但这在性能方面并不令人惊讶
正如我在下面所说的,您不能直接为UIBezierPath
的填充颜色设置动画。如果只想用现有代码更改填充颜色(而不是设置动画),则只需使用不同的userColor
调用setNeedsDisplay
如果你问这个问题是因为你使用了两种不同的路径进行掩蔽和填充,请参阅下面我的答案(事后看来过于复杂)
问题是
UIBezierPath
的填充颜色不可设置动画。但是CAShapeLayer
上的填充颜色为
因此,您需要使用另一个CAShapeLayer
进行填充。我建议您创建一个fillLayer
和一个maskLayer
属性,以明确它们的功能。现在,由于您使用的是100%分层方法,您可以将代码移出drawRect
,因为您不再进行任何核心图形绘制
另外,值得注意的是,您需要使用CGColor
作为动画的往返值
像这样的事情应该可以做到:
var fillColor = UIColor.greenColor()
let maskLayer = CAShapeLayer()
let fillLayer = CAShapeLayer()
func changeBackgroundColor() {
let animcolor = CABasicAnimation(keyPath: "fillColor")
animcolor.fromValue = UIColor.greenColor().CGColor
animcolor.toValue = UIColor.orangeColor().CGColor
animcolor.duration = 1.0;
animcolor.repeatCount = 0;
animcolor.autoreverses = true
fillLayer.addAnimation(animcolor, forKey: "fillColor")
}
// re-adjust the clipping path when the view bounds changes
override func layoutSubviews() {
let clipPath = UIBezierPath()
clipPath.moveToPoint(CGPointMake(self.bounds.minX + 7.65, self.bounds.minY - 0.25))
clipPath.addCurveToPoint(CGPointMake(self.bounds.minX + 7.65, self.bounds.minY + 36.1), controlPoint1: CGPointMake(self.bounds.minX - 2.38, self.bounds.minY + 9.79), controlPoint2: CGPointMake(self.bounds.minX - 2.38, self.bounds.minY + 26.06))
clipPath.addCurveToPoint(CGPointMake(self.bounds.minX + 43.99, self.bounds.minY + 36.1), controlPoint1: CGPointMake(self.bounds.minX + 17.69, self.bounds.minY + 46.13), controlPoint2: CGPointMake(self.bounds.minX + 33.96, self.bounds.minY + 46.13))
clipPath.addLineToPoint(CGPointMake(self.bounds.minX + 43.99, self.bounds.minY + 36.1))
clipPath.addLineToPoint(CGPointMake(self.bounds.minX + 44.01, self.bounds.minY + 0.19))
clipPath.addLineToPoint(CGPointMake(self.bounds.minX + 7.58, self.bounds.minY + 0.19))
// update layer paths
fillLayer.path = clipPath.CGPath
maskLayer.path = clipPath.CGPath
}
override init(frame: CGRect) {
super.init(frame: frame)
// configure filling
fillLayer.fillColor = fillColor.CGColor
fillLayer.fillRule = kCAFillRuleEvenOdd
// add fill path to superlayer
layer.addSublayer(fillLayer)
// configure masking layer
maskLayer.fillRule = kCAFillRuleEvenOdd
layer.mask = maskLayer
}
Swift 4版,你可以在操场上查看代码
var fillColor=UIColor.green
设maskLayer=CAShapeLayer()
设fillLayer=CAShapeLayer()
func changeBackgroundColor(){
让animcolor=cabasicanitation(关键路径:“fillColor”)
animcolor.fromValue=UIColor.green.cgColor
animcolor.toValue=UIColor.orange.cgColor
animcolor.duration=1.0;
animcolor.repeatCount=0;
animcolor.autoreverses=true
添加(animcolor,forKey:“fillColor”)
}
//视图边界更改时重新调整剪裁路径
let view=ui视图(帧:CGRect(x:0,y:0,宽度:300,高度:300))
view.backgroundColor=UIColor.white
func createpath(){
设clipPath=UIBezierPath()
移动(到:CGPoint(x:view.bounds.minX+7.65,y:view.bounds.minY-0.25))
clipPath.addCurve(to:CGPoint(x:view.bounds.minX+7.65,y:view.bounds.minY+36.1),
控制点1:CGPoint(x:view.bounds.minX-2.38,y:view.bounds.minY+9.79),
控制点2:CGPoint(x:view.bounds.minX-2.38,y:view.bounds.minY+26.06))
clipPath.addCurve(to:CGPoint(x:view.bounds.minX+43.99,y:view.bounds.minY+36.1),
控制点1:CGPoint(x:view.bounds.minX+17.69,y:view.bounds.minY+46.13),
控制点2:CGPoint(x:view.bounds.minX+33.96,y:view.bounds.minY+46.13))
clipPath.addLine(to:CGPoint(x:view.bounds.minX+43.99,y:view.bounds.minY+36.1))
clipPath.addLine(to:CGPoint(x:view.bounds.minX+44.01,y:view.bounds.minY+0.19))
clipPath.addLine(to:CGPoint(x:view.bounds.minX+7.58,y:view.bounds.minY+0.19))
//更新图层路径
fillLayer.path=clipPath.cgPath
maskLayer.path=clipPath.cgPath
fillLayer.fillColor=fillColor.cgColor
fillLayer.fillRule=.evenOdd
view.layer.addSublayer(fillLayer)
maskLayer.fillRule=.evenOdd
view.layer.mask=maskLayer
}
CreatePath()
太棒了。感谢您为更好的实施而努力。然而,我无法获得fillLayer
的填充颜色来设置动画,我甚至无法更改它。该函数肯定正在被调用,我正在记录它以确保。这就是我坐下来想在30-40分钟内完成的事情,结果花了半天的时间。@spacemonkey是fillLayer
在制作动画之前显示在屏幕上的吗?确保其frame
为非零,并将其添加到图层层次结构中。如果您使用的是我上面的代码,则需要使用init(frame:)
初始化器初始化UIView
(实际上,您希望将任何与大小相关的代码移动到更合适的位置,例如layoutSubviews
)。确切的位置和大小,它应该是。填充颜色也被设置为它应该的颜色,它只是不会改变为其他颜色。嗯。。。奇怪的在一个测试项目中,上面的代码对我来说运行良好。你确定把.CGColor
添加到动画的“到”和“从”值中了吗?我知道,没错,这太疯狂了。甚至注释掉整个类并逐字输入。