如何重复动画(使用UIViewPropertyAnimator)一定次数?

时间:2016-09-11 16:01:47

标签: swift animation ios10

我想实现按钮的脉动效果,因此需要多次重复弹簧效果,问题是我无法找到有关提供哪些参数以及如何操作的任何信息< / p>

let btnView = sayWordBtn.viewWithTag(0)
    btnView.transform = CGAffineTransform(scaleX: 0.7, y: 0.7)
    let mass: CGFloat = 2.0 // weight of the object
        let stiffness: CGFloat = 25.0 //elasticity
        let damping: CGFloat = 2*sqrt(mass*stiffness) // point where the system comes to rest in the shortest period of time
        let underDamping: CGFloat = damping * 0.5
        let initialVelocity: CGVector = CGVector.zero
        let springParameters: UISpringTimingParameters = UISpringTimingParameters(mass: mass, stiffness: stiffness, damping: underDamping, initialVelocity: initialVelocity)
        let animationDelay = 3

        let pulseEffect = UIViewPropertyAnimator(duration: 5, timingParameters: springParameters)
        pulseEffect.addAnimations( {[weak self] in
          btnView!.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
          })
        pulseEffect.isReversed = true
        pulseEffect.startAnimation(afterDelay: TimeInterval(animationDelay))

5 个答案:

答案 0 :(得分:10)

iOS 10 引入了一个名为UIViewPropertyAnimator的新对象。 您可以执行与UIView.animation相同的操作,但为了实现更复杂的动画,apple为我们提供了CoreAnimation框架。

我们为什么要使用它?

因为UIViewPropertyAnimator是一个编写良好且可高度扩展的API。它涵盖了许多与“旧式”UIView动画相同的功能,但为您提供了对动画的细粒度编程控制。这意味着您可以暂停正在进行的动画,如果您愿意,可以在以后重新启动动画,甚至动态修改动画属性(例如将动画的终点更改为屏幕的右上角,如果之前是底部的话 - 剩下)。 我们创建它的一个实例并创建一个动画,如下所示:

let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
view.alpha = 0.35 
view.backgroundColor = .red
self.view.addSubview(view)
let newFrame = CGRect(x: 0, y: 0, width: 50, height: 50)
let viewFrameAnimator = UIViewPropertyAnimator(duration: 1.0, 
                                                  curve: .linear, 
                                             animations: { view.frame = newFrame })

现在我们可以使用以下内容与动画进行交互:

viewFrameAnimator.startAnimation..
viewFrameAnimator.stopAnimation..
viewFrameAnimator.finishAnimation(at:..

继续上面的例子:

viewFrameAnimator.startAnimation()

然后,要返回alpha等于 1 ,如果我们需要更多动画选项,我们也可以启动this UIViewPropertyAnimator开放课程:

let viewAlphaAnimator = UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 1.0, 
                                                       delay: 0.0,
                                                     options: [.curveLinear],
                                                  animations: { view.alpha = 1.0 })

让我们添加更多动画选项。现在你知道的不仅仅是这个新对象。

如何重复?

让我们开始解释如何重复动画,例如,如果我们想要重复view.alpha = 1.0 3 次(你可以看到每次重复的小闪光灯输出..)你应该遵循:

let viewAlphaAnimator = UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 1.0,
                                                delay: 0.0,
                                                options: [.curveLinear,.repeat],
                                                animations: { UIView.setAnimationRepeatCount(3);view.alpha = 1.0 })

我希望这可以帮到你。

答案 1 :(得分:2)

请使用

    pulseEffect.addCompletion({_ in
            // Repeat the logic here
    })

您可以在addCompletion块

中重复动画逻辑
func animateView() {
    btnView.transform = CGAffineTransform(scaleX: 0.7, y: 0.7)
    let mass: CGFloat = 2.0 // weight of the object
    let stiffness: CGFloat = 25.0 // elasticity
    let damping: CGFloat = 2*sqrt(mass*stiffness) // point where the system comes to rest in the shortest period of time
    let underDamping: CGFloat = damping * 0.5
    let initialVelocity: CGVector = CGVector.zero
    let springParameters: UISpringTimingParameters = UISpringTimingParameters(mass: mass, stiffness: stiffness, damping: underDamping, initialVelocity: initialVelocity)
    let animationDelay = 3

    let pulseEffect = UIViewPropertyAnimator(duration: 5, timingParameters: springParameters)
    pulseEffect.addAnimations( {[weak self] in
        self?.btnView!.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
        })
    pulseEffect.addCompletion({_ in
        self.animateView()
    })
    pulseEffect.isReversed = true
    pulseEffect.startAnimation(afterDelay: TimeInterval(animationDelay))
}

您还可以添加逻辑以将动画限制为addCompletion块中的特定数字

答案 2 :(得分:2)

无论出于何种原因,他们都无法使用UIPropertyAnimator指定重复计数。你留下了以下选项:

  1. 保留计数器并在完成处理程序中重复动画 并递减计数器直到计数器达到0
  2. 使用无限期重复动画,但安排计时器并暂停 动画(可选择添加动画以移动到最终 位置)
  3. 调整弹簧参数,以减少阻尼和 更有弹性,你会得到更多的振动。
  4. 使用旧的UIView.animate方法和旧方法 UIView.setAnimationRepeatCount
  5. 使用CASpringAnimation,因为这就是Property animator正在包装的东西,它确实有重复计数。

答案 3 :(得分:1)

'setAnimationRepeatCount'在iOS 13.0中已弃用。选项:[.autoreverse,.repeat]也不起作用。

en

答案 4 :(得分:0)

请使用此修改后的代码

let btnView = sayWordBtn.viewWithTag(0)
btnView.transform = CGAffineTransform(scaleX: 0.7, y: 0.7)
let mass: CGFloat = 2.0 // weight of the object
let stiffness: CGFloat = 25.0 //elasticity
let damping: CGFloat = 2*sqrt(mass*stiffness) // point where the system comes to rest in the shortest period of time
let underDamping: CGFloat = damping * 0.5
let initialVelocity: CGVector = CGVector.zero
let springParameters: UISpringTimingParameters = UISpringTimingParameters(mass: mass, stiffness: stiffness, damping: underDamping, initialVelocity: initialVelocity)
let animationDelay = 3

let pulseEffect = UIViewPropertyAnimator(duration: 5, timingParameters: springParameters)
pulseEffect.addAnimations( {[weak self] in
    UIView.setAnimationRepeatCount(3)
    UIView.setAnimationRepeatAutoreverses(true)
    btnView!.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
})
pulseEffect.isReversed = true
pulseEffect.startAnimation(afterDelay: TimeInterval(animationDelay))