就像我正在寻找的改变 UIView 的背景颜色一样。
But why你不能完全那样做吗?您已经将视图遮盖到您的路径上 - 因此设置背景颜色的动画将达到您想要的确切效果。只需摆脱 Core Graphics 路径填充 - 并删除drawRect
覆盖,如你不能使用drawRect带有背景动画 https://stackoverflow.com/a/28902900/2976878.
If you really需要使用drawRect
并设置颜色动画,您可以考虑拆分您的UIView
一分为二UIViews
- 一个用于绘制背景图层(您可以为其设置动画),另一个用于绘制自定义绘图。或者,你could设置一个CADisplayLink
使用中间背景颜色重新绘制每一帧的视图 - 但这在性能方面并不令人惊奇。
正如我下面所说,你不能为 a 的填充颜色设置动画UIBezierPath
直接地。如果您只想使用现有代码更改(而不是动画)填充颜色,那么您只需调用setNeedsDisplay
与不同的userColor
.
如果您问这个问题是因为您使用两种不同的路径进行掩蔽和填充,请参阅我下面的答案(事后看来过于复杂)。
问题是 a 的填充颜色UIBezierPath
不可设置动画。但是a上的填充颜色CAShapeLayer
is.
因此你想使用另一个CAShapeLayer
代替填充物。我建议你创建一个fillLayer
and a maskLayer
属性,以明确其功能。现在,因为您使用的是 100% 分层方法,所以您可以将代码移出drawRect
,因为您不再进行任何 Core Graphics 绘图。
另外,值得注意的是,您需要使用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
}