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

spi*_*ght 13 animation swift ios10

我想为按钮实现脉动效果,因此需要多次重复弹簧效果,问题是我找不到任何关于提供什么参数的信息以及如何做到这一点

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))
Run Code Online (Sandbox Code Playgroud)

Ale*_*ano 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 })
Run Code Online (Sandbox Code Playgroud)

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

viewFrameAnimator.startAnimation..
viewFrameAnimator.stopAnimation..
viewFrameAnimator.finishAnimation(at:..
Run Code Online (Sandbox Code Playgroud)

继续上面的例子:

viewFrameAnimator.startAnimation()
Run Code Online (Sandbox Code Playgroud)

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

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

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

怎么重复一遍?

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

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

我希望这可以帮到你.

  • 难道你不得不发送`UIView.setAnimationRepeatCount()`,基本上是来自旧API的类侧全局设置,这表明这个新框架实际上并不比旧框架更好或更强大?也许对于简单的案例更为简洁,但这并不会让我感到优雅或强大.如果UIViewPropertyAnimator像其他动画对象一样有一个repeatCount,那将是"更正确"的东西,IMO. (11认同)
  • setAnimationRepeatCount 已弃用。现在我们如何重复它? (2认同)

Mau*_*ime 5

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

var animator: UIViewPropertyAnimator!

func start(_ reversed: Bool = false) {
    animator = UIViewPropertyAnimator()
    animator.addAnimations {
        //
    }
    animator.addCompletion { _ in
        start(!reversed)
    }
    animator.startAnimation()
}

func stop() {
    animator.stopAnimation(true)
}
Run Code Online (Sandbox Code Playgroud)


Lin*_*han 2

请用

    pulseEffect.addCompletion({_ in
            // Repeat the logic here
    })
Run Code Online (Sandbox Code Playgroud)

您可以在 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))
}
Run Code Online (Sandbox Code Playgroud)

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