UIView.animateにおけるEasingへの疑いを晴らす - そして信用へ -


こいつ、ほんまにEasingしてっか?

ってときありません?
僕はあったんですよ。
やから、今回。

ほんまにEasingしてっか、ちゃんと確かめよう
ってなったわけです。

実証

ついでやし、

  • linear
  • easeIn
  • easeOut
  • easeInOut

の4つで2パターン試してみることにします。
(とりあえず試すために、コードは各所はいぱー簡易的です)

UIView.animateのoptionsに、各Easingが指定できまして、それぞれ

  • linear:curveLinear
  • easeIn:curveEaseIn
  • easeOut:curveEaseOut
  • easeInOut:curveEaseInOut

こんな感じです。

(勘の良い方はお気づきだと思いますが、optionsっていうわざわざ複数形になっているので、他のoptionも同時に設定することができます。その辺はキャッツアイ。)

パターンA:AutoLayoutで試す


@IBOutlet private weak var viewATopConstraint: NSLayoutConstraint!
@IBOutlet private weak var viewBTopConstraint: NSLayoutConstraint!
@IBOutlet private weak var viewCTopConstraint: NSLayoutConstraint!
@IBOutlet private weak var viewDTopConstraint: NSLayoutConstraint!

private func animateAutoLayout() {
    self.viewATopConstraint.constant = 300
    UIView.animate(withDuration: 1.0, delay: 0, options: .curveLinear, animations: {
        self.view.layoutIfNeeded()
    }, completion: nil)

    self.viewBTopConstraint.constant = 300
    UIView.animate(withDuration: 1.0, delay: 0, options: .curveEaseIn, animations: {
        self.view.layoutIfNeeded()
    }, completion: nil)

    self.viewCTopConstraint.constant = 300
    UIView.animate(withDuration: 1.0, delay: 0, options: .curveEaseOut, animations: {
        self.view.layoutIfNeeded()
    }, completion: nil)

    self.viewDTopConstraint.constant = 300
    UIView.animate(withDuration: 1.0, delay: 0, options: .curveEaseInOut, animations: {
        self.view.layoutIfNeeded()
    }, completion: nil)
}

これで動かすと

Easingしてんな!

パターンB:y位置調整で試す


@IBOutlet private weak var viewA: UIView!
@IBOutlet private weak var viewB: UIView!
@IBOutlet private weak var viewC: UIView!
@IBOutlet private weak var viewD: UIView!

private func animateFrame() {
    UIView.animate(withDuration: 1.0, delay: 0, options: .curveLinear, animations: {
        self.viewA.frame.origin.y += 300
    }, completion: nil)

    UIView.animate(withDuration: 1.0, delay: 0, options: .curveEaseIn, animations: {
        self.viewB.frame.origin.y += 300
    }, completion: nil)

    UIView.animate(withDuration: 1.0, delay: 0, options: .curveEaseOut, animations: {
        self.viewC.frame.origin.y += 300
    }, completion: nil)

    UIView.animate(withDuration: 1.0, delay: 0, options: .curveEaseInOut, animations: {
        self.viewD.frame.origin.y += 300
    }, completion: nil)
}

こいつはどうだろう

いや、Easingしてんな!

余談

これ余談なんですけど。
Easingしてるっていうのは、言葉的にはアレなんですが、今回カミ○リ風に仕上げるためにこういう表現をさせていただいています。おす。
(あくまで口調が風なだけです)
その辺を把握した上で、もう一回読んでいただけたら

なるほど

ってなる。(ってくれたら嬉しいです。)
あと、おはぎはきなこ派です。

結果

Easingしとりましたわ。
(いや、そりゃそうやろって話なのだが)
(まぁ、当たり前を当たり前だと思わない的なあれですよ)

ちなみに、まぁこれも当たり前って言ってしまえばそこまでですが。
パターンAとBが違う動画であることを強調するためにわざわざViewの色を赤と青にしていますが、全く同じ動きをしていました。
(これが真の余談だったりもする、説)

何が言いたいかというとですね、ええ

つまり、UIView.animateはちゃんとEasingしていて、同じ時間をかけてのアニメーションでも動き方はこんなに違ってくるから、使用箇所使用タイミングに応じて使い分けてあげましょうってことですね、ええ。
(ごまかした)

みなさんも、この子のことは疑わずに信用して実装してあげましょう。

(M-1が近いということで、もれなくそっち方面の色が強めに出ていますが、多めに見てください)