CABaseAnimation 委托

CABaseAnimation Delegate

我用CABaseAnimation创建图层的动画,并将CABaseAnimation的委托设置为viewController,代码如下:

let flyRight = CABasicAnimation(keyPath: "position.x")
    flyRight.delegate = self
    flyRight.toValue = view.bounds.size.width/2
    flyRight.fromValue = -view.bounds.size.width/2
    flyRight.fillMode = kCAFillModeBoth
    flyRight.duration = 0.5

    flyRight.setValue(heading.layer, forKey: "heading")
    heading.layer.addAnimation(flyRight, forKey: nil)

    flyRight.beginTime = CACurrentMediaTime() + 0.3
    flyRight.setValue(username.layer, forKey: "username")
    username.layer.addAnimation(flyRight, forKey: nil)

    username.layer.position.x = view.bounds.size.width/2

    flyRight.beginTime = CACurrentMediaTime() + 0.4
    flyRight.setValue(password.layer, forKey: "password")
    password.layer.addAnimation(flyRight, forKey: nil)
    password.layer.position.x = view.bounds.size.width/2

委托animationDidStop方法代码如下:

 override func animationDidStop(anim: CAAnimation, finished flag: Bool) {
    print(anim)
    if let layer = anim.valueForKey("heading") as? CALayer {
        anim.setValue(nil, forKey: "heading")
        let animation = CABasicAnimation(keyPath: "transform.scale")
        animation.fromValue = 1.0
        animation.toValue = 1.5
        animation.duration = 1.0
        layer.addAnimation(animation, forKey: nil)
        print("heading layer animation did stop")
        }
    }

但在委托方法中我发现控制台打印了三次"heading layer animation did stop",这是控制台中的打印行:

<CABasicAnimation: 0x7fbe13096b10>
heading layer animation did stop
<CABasicAnimation: 0x7fbe13020bf0>
heading layer animation did stop
<CABasicAnimation: 0x7fbe13096c80>
heading layer animation did stop

我很困惑为什么打印方法执行了三次。

你的代码说(本质上):

flyRight.delegate = self
flyRight.setValue(heading.layer, forKey: "heading")
heading.layer.addAnimation(flyRight, forKey: nil)
username.layer.addAnimation(flyRight, forKey: nil)
password.layer.addAnimation(flyRight, forKey: nil)

因此您要将此动画添加到三个不同的层。在此之前,您将其 "heading" 键设置为 heading.layer,并将动画的 delegate 设置为 self。因此,我们有一个三层 运行 动画,其中 delegateself 并且 "heading" 键是 heading.layer.

现在我们来处理您的 animationDidStop 处理程序:

override func animationDidStop(anim: CAAnimation, finished flag: Bool) {
    if let layer = anim.valueForKey("heading") as? CALayer {
        print(/*...*/)
    }
}

因此所有三个动画最终都调用了 animationDidStop 处理程序,并且在所有三个动画中 if let layer 测试 通过了 ;他们三个确实都有一个键"heading",它是一个 CALayer。因此,您会看到打印输出的所有 3 次。很明显。

(的确,唯一明显的是你为什么感到惊讶。我能想到的唯一解释是你没有意识到 addAnimation:forKey: 添加了一个 copy 的动画。这是一些人没有意识到的事情。但是很难理解为什么没有意识到会导致你在这种特殊情况下感到惊讶。)