LoginSignup
9

More than 5 years have passed since last update.

UIView.animateWithDurationのinitialSpringVelocityについて

Last updated at Posted at 2015-08-04

今更ですが、UIViewにiOS7で追加された、animateWithDuration:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completionの、initialSpringVelocityブロパティが何を示しているのか、Google先生も教えてくれなかったので調べました。

頑張って簡単に答えをいうと、アニメーションの初速が、
「アニメーション全体をLinearに1秒で終わらせる速度の何倍の速度か」
を示すプロパティのようです。混乱しますが、
「アニメーション全体をLinearに何秒で終わらせる速度か」
ではありません。

リファレンスを読むと、

A value of 1 corresponds to the total animation distance traversed in one second.
For example, if the total animation distance is 200 points and you want the start of the animation to match a view velocity of 100 pt/s, use a value of 0.5.

と書いてあり、全体が200ptを動くアニメーションで、初速を100pt/sにしたい場合、200ptを1秒で終わらせる速度(200pt/s)の1/2なので、0.5になります。

このパラメータは、ユーザのフリックで物体を動かすときにユーザのフリック速度からスムーズにアニメーションに繋げたいような場合に便利です。
例えば指にy軸だけついてくるアニメーションを考えると、

ViewController.swift
class ViewController: UIViewController {
    @IBOutlet weak var topConstraint: NSLayoutConstraint! //動かすviewの上からの距離の制約
    private var topConstraintConstantWhenBegan = CGFloat(0) //動かしはじめの上からの距離保存用変数
    private let minTopConstraintConstant = CGFloat(0) //動かすviewの上からの最小の距離
    private var maxTopConstraintConstant: CGFloat { //動かすviewの上からの最大の距離
        get { return view.frame.height - 50 - topLayoutGuide.length }
    }

    @IBAction func panned(sender: UIPanGestureRecognizer) {
        switch sender.state {
        case .Began: //保存
            topConstraintConstantWhenBegan = topConstraint.constant
        case .Changed: //指についてくる
            topConstraint.constant = sender.translationInView(view).y + topConstraintConstantWhenBegan
        case .Ended: //アニメーション
            let velocity = sender.velocityInView(view).y //離した瞬間の速度
            let beforeConstant = topConstraint.constant //離した瞬間の上からの距離
            let afterConstant = velocity > 0 ? maxTopConstraintConstant : minTopConstraintConstant //アニメーション後の上からの距離
            let distance = afterConstant - beforeConstant //アニメーションする距離

            topConstraint.constant = afterConstant

            UIView.animateWithDuration(3, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: velocity / distance, options: .CurveLinear, animations: {
                self.view.layoutIfNeeded()
            }, completion: nil)
        default: break
        }
    }
}

initialSprintVelocityが、velocity / distance になっています。
大分混乱するのですが、1秒でアニメーションが終わる速度は、distance(pt) / 1(s) = distance(pt/s) です。
なので、velocity(pt/s) / distance(pt/s)が、initialSpringVelocityになります。

コード

https://github.com/malt03/Animation
Xcode7で作ってます。適当にpushしただけなので、動くか分かりません。

リファレンス

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9