iOS 动画:CADisplayLink 与 CAShapeLayer
iOS Animation: CADisplayLink vs CAShapeLayer
我正在编写一个计时器,类似于水平版时钟应用程序中可用的计时器,不同之处在于它从满开始到空。
我实现了计时器,它适用于更长的时间,但它无法足够快地制作动画以实现快速动画(我的目标是最快达到 400 毫秒的总动画时间),因为我使用 drawRect 方法制作动画。为了说明,这是我的计时器代码:
class SSTimerView: UIView {
var timer: NSTimer?
var startAngle: CGFloat = (CGFloat) (M_PI * 1.5)
var endAngle: CGFloat = (CGFloat) (M_PI * 1.5) + (CGFloat) (M_PI * 2)
var percent: CGFloat? = 100
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func drawRect(rect: CGRect) {
var bezierPath = UIBezierPath()
//Create our arc with the correct angles
bezierPath.addArcWithCenter(CGPointMake(rect.size.width/2, rect.size.height/2),
radius: 130,
startAngle: startAngle,
endAngle: (endAngle - startAngle) * (percent! / 100.0) + startAngle,
clockwise: true
)
//Set the display for the path and stroke it.
bezierPath.lineWidth = 20
Slide.sharedInstance.currentInstruction!.colorFamily.lighterColor.setStroke()
bezierPath.stroke()
}
}
我一直在研究 CADisplayLink,我认为它可能是一个可行的选择,但我也听说 CADisplayLink 并不适用于所有情况。这是其中之一吗?如果 CADisplayLink 在这里不合适,我应该使用什么 CA class?
如您所知,手动设置动画时 CADisplayLink
总是比 NSTimer
好。 (有关原因的讨论,请参阅 WWDC 2014 视频 Building Interruptible and Responsive Interactions,从视频开始大约 14 分钟开始。)因此,如果您坚持现有模式,一定要转向 CADisplayLink
。
但是如果你想为这条路径的绘图设置动画,CABasicAnimation
就容易多了:
var shapeLayer: CAShapeLayer!
func addShapeLayer() {
shapeLayer = CAShapeLayer()
let startAngle = CGFloat(M_PI * 1.5)
let endAngle = startAngle + CGFloat(M_PI * 2)
let bezierPath = UIBezierPath()
bezierPath.addArcWithCenter(CGPointMake(view.bounds.size.width/2, view.bounds.size.height/2),
radius: 130.0,
startAngle: startAngle,
endAngle: endAngle,
clockwise: true
)
shapeLayer.path = bezierPath.CGPath
shapeLayer.strokeColor = UIColor.blueColor().CGColor
shapeLayer.fillColor = UIColor.clearColor().CGColor
shapeLayer.lineWidth = 20.0
view.layer.addSublayer(shapeLayer)
}
func animateShapeLayer() {
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.duration = 0.4
animation.fromValue = 0.0
animation.toValue = 1.0
shapeLayer.addAnimation(animation, forKey: "strokeEndAnimation")
}
如果您需要更多自定义行为,CADisplayLink
方法非常好,但如果您只想在一定时间内为路径的绘制设置动画,CABasicAnimation
是最简单的(并且很可能提供最佳性能)。
我正在编写一个计时器,类似于水平版时钟应用程序中可用的计时器,不同之处在于它从满开始到空。
我实现了计时器,它适用于更长的时间,但它无法足够快地制作动画以实现快速动画(我的目标是最快达到 400 毫秒的总动画时间),因为我使用 drawRect 方法制作动画。为了说明,这是我的计时器代码:
class SSTimerView: UIView {
var timer: NSTimer?
var startAngle: CGFloat = (CGFloat) (M_PI * 1.5)
var endAngle: CGFloat = (CGFloat) (M_PI * 1.5) + (CGFloat) (M_PI * 2)
var percent: CGFloat? = 100
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func drawRect(rect: CGRect) {
var bezierPath = UIBezierPath()
//Create our arc with the correct angles
bezierPath.addArcWithCenter(CGPointMake(rect.size.width/2, rect.size.height/2),
radius: 130,
startAngle: startAngle,
endAngle: (endAngle - startAngle) * (percent! / 100.0) + startAngle,
clockwise: true
)
//Set the display for the path and stroke it.
bezierPath.lineWidth = 20
Slide.sharedInstance.currentInstruction!.colorFamily.lighterColor.setStroke()
bezierPath.stroke()
}
}
我一直在研究 CADisplayLink,我认为它可能是一个可行的选择,但我也听说 CADisplayLink 并不适用于所有情况。这是其中之一吗?如果 CADisplayLink 在这里不合适,我应该使用什么 CA class?
如您所知,手动设置动画时 CADisplayLink
总是比 NSTimer
好。 (有关原因的讨论,请参阅 WWDC 2014 视频 Building Interruptible and Responsive Interactions,从视频开始大约 14 分钟开始。)因此,如果您坚持现有模式,一定要转向 CADisplayLink
。
但是如果你想为这条路径的绘图设置动画,CABasicAnimation
就容易多了:
var shapeLayer: CAShapeLayer!
func addShapeLayer() {
shapeLayer = CAShapeLayer()
let startAngle = CGFloat(M_PI * 1.5)
let endAngle = startAngle + CGFloat(M_PI * 2)
let bezierPath = UIBezierPath()
bezierPath.addArcWithCenter(CGPointMake(view.bounds.size.width/2, view.bounds.size.height/2),
radius: 130.0,
startAngle: startAngle,
endAngle: endAngle,
clockwise: true
)
shapeLayer.path = bezierPath.CGPath
shapeLayer.strokeColor = UIColor.blueColor().CGColor
shapeLayer.fillColor = UIColor.clearColor().CGColor
shapeLayer.lineWidth = 20.0
view.layer.addSublayer(shapeLayer)
}
func animateShapeLayer() {
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.duration = 0.4
animation.fromValue = 0.0
animation.toValue = 1.0
shapeLayer.addAnimation(animation, forKey: "strokeEndAnimation")
}
如果您需要更多自定义行为,CADisplayLink
方法非常好,但如果您只想在一定时间内为路径的绘制设置动画,CABasicAnimation
是最简单的(并且很可能提供最佳性能)。