我尝试用CATransaction
练习CABasicAnimation
和CAShapeLayer
,我按照自己的意愿完美地完成了动画制作工作,但动画完成后的块并未立即调用动画结束了。
以下是我使用的关键代码:
func startAnimation(){
CATransaction.begin()
CATransaction.setAnimationDuration(10.0)
let pathAnimation = CABasicAnimation(keyPath: "strokeEnd")
pathAnimation.duration = 10.0
pathAnimation.fromValue = 0.0 as NSNumber
pathAnimation.toValue = 1.0 as NSNumber
CATransaction.setCompletionBlock { () -> Void in
NSLog("finished")
}
pathLayer.addAnimation(pathAnimation, forKey: "strokeEnd")
self.layer.addSublayer(pathLayer)
CATransaction.commit()
NSLog("start")
}
2 NSLog的输出如下所示:
2015-01-14 00:30:05.549 QuartzCorePlayground[47369:2769473] start
2015-01-14 00:30:22.004 QuartzCorePlayground[47369:2769473] finished
为什么
finished
总是在动画结束后大约6.5秒打印出来?我的代码出了什么问题?
原因是,正如评论中所提到的,它似乎是Xcode游戏中的一个错误,当我把代码放在真实项目中时,它就像我对CoreAnimation的理解一样。
以下是我在Xcode游乐场中运行的完整代码(您需要检查Xcode中的 Run in Full Simulator
选项)
// Playground - noun: a place where people can play
import UIKit
import XCPlayground
func radians(degree : CGFloat) -> CGFloat{
return CGFloat((Double(degree) / 180) * M_PI)
}
class TimerShapeView : UIView {
var pathLayer = CAShapeLayer()
override init(frame: CGRect) {
super.init(frame: frame)
let innerSize : CGFloat = 20
var squareRectSize = min(CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds))
var squareRect = CGRectInset(self.bounds, (CGRectGetWidth(self.bounds) - squareRectSize)/2 + innerSize, (CGRectGetHeight(self.bounds) - squareRectSize)/2 + innerSize)
let workoutPath = UIBezierPath()
workoutPath.addArcWithCenter(CGPoint(x: CGRectGetMidX(squareRect), y: CGRectGetMidY(squareRect)), radius: CGRectGetWidth(squareRect)/2, startAngle: radians(90), endAngle: radians(360), clockwise: true)
pathLayer.frame = self.bounds
pathLayer.path = workoutPath.CGPath
pathLayer.lineWidth = 2.0
pathLayer.strokeColor = UIColor.purpleColor().CGColor
pathLayer.geometryFlipped = true
pathLayer.fillColor = nil
pathLayer.lineJoin = kCALineJoinBevel
self.layer.addSublayer(pathLayer)
self.backgroundColor = UIColor.greenColor().colorWithAlphaComponent(0.1)
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func startAnimation(){
CATransaction.begin()
CATransaction.setAnimationDuration(10.0)
let pathAnimation = CABasicAnimation(keyPath: "strokeEnd")
pathAnimation.duration = 10.0
pathAnimation.fromValue = 0.0 as NSNumber
pathAnimation.toValue = 1.0 as NSNumber
CATransaction.setCompletionBlock { () -> Void in
NSLog("finished")
}
pathLayer.addAnimation(pathAnimation, forKey: "strokeEnd")
self.layer.addSublayer(pathLayer)
CATransaction.commit()
NSLog("start")
}
}
var shapeTimerView = TimerShapeView(frame: CGRect(x: 0, y: 0, width: 320, height: 220))
XCPShowView("newTimerView", shapeTimerView)
shapeTimerView.startAnimation()