34

我有一个CAKeyframeAnimation动画,我想永远重复使用repeatCount = HUGE_VALF. 动画的持续时间为 2 秒,但我想在每个循环之前暂停 3 秒。

我能想到的唯一两种方法是:

  1. 使整个动画持续 5 秒并添加额外的 keyTimes 和值,以便在 5 秒动画的最后 3 秒内获得我正在寻找的暂停。这感觉有点hacky。

  2. 让动画只重复一次,然后添加使用类似的东西performSelector:afterDelay:2再次运行动画,依此类推。这也感觉很脏。也意味着我需要addAnimation:每 5 秒调用一次,我不确定这在性能方面是否最佳。

我可能会错过其他选择吗?这两种方法中的一种是否比另一种更好?

4

3 回答 3

128

通过转储 Apple 的动画MKUserLocationView,我能够看到他们是如何做到的。原来这是CAAnimationGroup为了这个。通过将 2 秒的动画封装到 5 秒的动画组中,您将得到一个 2 秒的动画,然后是 3 秒的延迟:

CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
animationGroup.duration = 5;
animationGroup.repeatCount = INFINITY;

CAMediaTimingFunction *easeOut = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];

CABasicAnimation *pulseAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale.xy"];
pulseAnimation.fromValue = @0.0;
pulseAnimation.toValue = @1.0;
pulseAnimation.duration = 2;
pulseAnimation.timingFunction = easeOut;

animationGroup.animations = @[pulseAnimation];

[ringImageView.layer addAnimation:animationGroup forKey:@"pulse"];
于 2013-03-03T23:39:47.590 回答
8

samvermette 在 Swift 3 中的回答:

let animationGroup = CAAnimationGroup()
animationGroup.duration = 5;
animationGroup.repeatCount = .infinity

let easeOut = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)

let pulseAnimation = CABasicAnimation(keyPath: "transform.scale.xy")
pulseAnimation.fromValue = 0
pulseAnimation.toValue = 1.0
pulseAnimation.duration = 2
pulseAnimation.timingFunction = easeOut

animationGroup.animations = [pulseAnimation]

ringImageView.layer.add(animationGroup, forKey: "pulse")
于 2017-01-12T01:57:31.727 回答
0

在 Swift 4.2 上测试

只需实现以下扩展,然后您就可以在任何 UI 组件上获得漂亮的脉冲动画

//MARK:- Pulse animation
extension UIView {
    
    func applyPulse(_ apply: Bool = true) {
        if apply {
            let animation = CABasicAnimation(keyPath: "transform.scale")
            animation.toValue = 1.5
            animation.duration = 0.8
            animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeOut)
            animation.autoreverses = true
            animation.repeatCount = Float.infinity
            self.layer.add(animation, forKey: "pulsing")
        } else {
            self.layer.removeAnimation(forKey: "pulsing")
        }
    }
}

用法:

  1. 开始

    yourUiComponent.applyPulse()

  2. 停止

    yourUiComponent.applyPulse(false)

于 2019-04-17T00:33:09.757 回答