考虑使用CADisplayLink
实现此简单的同步动画,
var link:CADisplayLink?
var startTime:Double = 0.0
let animTime:Double = 0.2
let animMaxVal:CGFloat = 0.4
private func yourAnim()
{
if ( link != nil )
{
link!.paused = true
//A:
link!.removeFromRunLoop(
NSRunLoop.mainRunLoop(), forMode:NSDefaultRunLoopMode)
link = nil
}
link = CADisplayLink(target: self, selector: #selector(doorStep) )
startTime = CACurrentMediaTime()
link!.addToRunLoop(
NSRunLoop.currentRunLoop(), forMode:NSDefaultRunLoopMode)
}
func doorStep()
{
let elapsed = CACurrentMediaTime() - startTime
var ping = elapsed
if (elapsed > (animTime / 2.0)) {ping = animTime - elapsed}
let frac = ping / (animTime / 2.0)
yourAnimFunction(CGFloat(frac) * animMaxVal)
if (elapsed > animTime)
{
//B:
link!.paused = true
link!.removeFromRunLoop(
NSRunLoop.mainRunLoop(), forMode:NSDefaultRunLoopMode)
link = nil
yourAnimFunction(0.0)
}
}
func killAnimation()
{
// for example if the cell disappears or is reused
//C:
????!!!!
}
似乎存在各种问题。
在(A:)处,即使link
不为空,也可能无法将其从运行循环中删除。(例如,有人可能使用link = link:CADisplayLink()
进行初始化-尝试会引起崩溃)
其次,在(B:)处,情况似乎很混乱...肯定有更好(且更符合Swift风格)的方法,如果时间刚好过期,又该怎么办?
最后,在(C:)处,如果想要中断动画...我感到沮丧,不知道什么是最好的选择。
而且,实际上,A:和B:处的代码应该是相同的调用,这是一种清理调用。
invalidate()
会从所有运行循环模式中移除给定的显示链接,这将导致它从运行循环中释放。 - Hamish