第四步线条恢复的原来长度的动画
这里我们还是使用CABasicAnimation基础动画,keyPath作用于线条的strokeEnd属性,让strokeEnd从0到1来实现线条长短的动画,下面是效果图和代码:

/**
线的第三步动画,线由短变长
*/
private func lineAnimationThree() {
//线移动的动画
let lineAnimationFour = CABasicAnimation.init(keyPath: "strokeEnd")
lineAnimationFour.beginTime = CACurrentMediaTime() + duration
lineAnimationFour.duration = duration/4
lineAnimationFour.fillMode = kCAFillModeForwards
lineAnimationFour.removedOnCompletion = false
lineAnimationFour.fromValue = 0
lineAnimationFour.toValue = 1
for i in 0...3 {
if i == 3 {
lineAnimationFour.delegate = self
}
let lineLayer = lines[i]
lineLayer.addAnimation(lineAnimationFour, forKey: "lineAnimationFour")
}
}
最后一步需要将动画组合起来
关于动画组合我没用到CAAnimationGroup,因为这些动画并不是加到同一个layer上,再加上动画类型有点多加起来也比较麻烦,我就通过动画的beginTime属性来控制动画的执行顺序,还加了动画暂停和继续的功能,效果和代码见下图:

//MARK: Public Methods
/**
开始动画
*/
func startAnimation() {
angleAnimation()
lineAnimationOne()
lineAnimationTwo()
lineAnimationThree()
}
/**
暂停动画
*/
func pauseAnimation() {
layer.pauseAnimation()
for lineLayer in lines {
lineLayer.pauseAnimation()
}
status = .pause
}
/**
继续动画
*/
func resumeAnimation() {
layer.resumeAnimation()
for lineLayer in lines {
lineLayer.resumeAnimation()
}
status = .Animating
}
extension CALayer {
//暂停动画
func pauseAnimation() {
// 将当前时间CACurrentMediaTime转换为layer上的时间, 即将parent time转换为localtime
let pauseTime = convertTime(CACurrentMediaTime(), fromLayer: nil)
// 设置layer的timeOffset, 在继续操作也会使用到
timeOffset = pauseTime
// localtime与parenttime的比例为0, 意味着localtime暂停了
speed = 0;
}
//继续动画
func resumeAnimation() {
let pausedTime = timeOffset
speed = 1
timeOffset = 0;
beginTime = 0
// 计算暂停时间
let sincePause = convertTime(CACurrentMediaTime(), fromLayer: nil) - pausedTime
// local time相对于parent time时间的beginTime
beginTime = sincePause
}
}
//MARK: Animation Delegate
override func animationDidStart(anim: CAAnimation) {
if let animation = anim as? CABasicAnimation {
if animation.keyPath == "transform.rotation.z" {
status = .Animating
}
}
}
override func animationDidStop(anim: CAAnimation, finished flag: Bool) {
if let animation = anim as? CABasicAnimation {
if animation.keyPath == "strokeEnd" {
if flag {
status = .Normal
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(interval) * Int64(NSEC_PER_SEC)), dispatch_get_main_queue(), {
if self.status != .Animating {
self.startAnimation()
}
})
}
}
}
}
//MARK: Override
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
switch status {
case .Animating:
pauseAnimation()
case .pause:
resumeAnimation()
case .Normal:
startAnimation()
}
}










