web-dev-qa-db-ja.com

(UIViewPropertyAnimatorを使用して)アニメーションを特定の回数繰り返すにはどうすればよいですか?

ボタンの脈動効果を実現したいので、スプリング効果を数回繰り返す必要があります。問題は、提供するパラメーターとその方法に関する情報が見つからないことです。

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))
15
spin_eight

iOS 1は、 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と等しくし、さらにアニメーションオプションが必要な場合は、 thisUIViewPropertyAnimatorオープンクラス:

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

アニメーションオプションを追加してみましょう。今、あなたはこの新しいオブジェクト以上のものを知っています。

それを繰り返す方法は?

それでは、たとえばview.alpha = 1.0を回繰り返したい場合など、アニメーションを繰り返す方法の説明を始めましょう(出力の繰り返しごとに小さなフラッシュライトが表示されます。)あなたは従うべきです:

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

これがお役に立てば幸いです。

10

何らかの理由で、UIPropertyAnimatorで繰り返し回数を指定する機能を省略しました。次のオプションが残っています。

  1. カウンターを保持し、完了ハンドラーでアニメーションを繰り返し、カウンターが0になるまでカウンターをデクリメントします
  2. 無期限の繰り返しでアニメーション化しますが、タイマーをスケジュールしてアニメーションを停止します(オプションで、最終位置に移動するアニメーションを追加します)
  3. スプリングパラメータを調整して、減衰が少なくなり、弾力性が高まり、振動が増えるようにします。
  4. 古いUIView.animateメソッドを古い IView.setAnimationRepeatCount と共に使用します
  5. とにかくプロパティアニメーターがラップするのはCASpringAnimationであり、繰り返し回数があります。
3
Josh Homann

使ってください

    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
Lineesh K Mohan

'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)
}
1
Catt Liu

このコードは機能します:

func usePropertyAnimator(_ reversed: Bool = false) {

    let circleAnimator = UIViewPropertyAnimator(
        duration: 2, timingParameters: UICubicTimingParameters())

    circleAnimator.addAnimations {
        circle.center.y += (reversed ? -1 : 1) * 330
    }

    circleAnimator.addCompletion { _ in
        usePropertyAnimator(!reversed)
    }

    circleAnimator.startAnimation()

}

usePropertyAnimator()
0
Rain

この変更されたコードを使用してください

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))
0
Arun Ammannaya