システム標準っぽいアニメーション

# はじめに

一昔前の話になりますが、iOS 7から標準のアニメーションカーブが変更されたのはご存知でしょうか。勘の良い方なら、モーダルビューやプッシュなどのアニメーションがiOS 6以前よりも勾配が大きくなったようなイージングに変わったということにすぐ気付いたかと思います。しかしこのアニメーションカーブは UIViewAnimation や Core Animation では定数として用意されておらず、システム標準っぽいアニメーションに近づけるためには独自にカーブを設計するしか方法がないものと思っていました。……実はあるんです。iOS 7で UIView に追加されたメソッドを使えば、システム標準っぽいアニメーションを UIViewAnimation として適用することができます。お恥ずかしいことに3年経ってようやくそのメソッドの存在を知りまして、[ググってみても](https://www.google.co.jp/search?q=performSystemAnimation)情報量が圧倒的に少ない様子でしたので、ここに記しておくことにしました。


# performSystemAnimation:onViews:options:animations:completion:

<del>API Reference には記載がないのですが、</del>UIView に public として公開されているメソッドなので問題ないでしょう。このメソッドを使えばシステム標準っぽいアニメーションを再現できます。アニメーションのカーブや長さは規定のものが適用されるので変更できませんが、『システム標準っぽくする』という要件であれば問題ないでしょう。なお `options` に `.CurveEaseOut` などを指定しても無視されます。

```swift:UIView
/* Performs the requested system-provided animation on one or more views. Specify addtional animations in the parallelAnimations block. These additional animations will run alongside the system animation with the same timing and duration that the system animation defines/inherits. Additional animations should not modify properties of the view on which the system animation is being performed. Not all system animations honor all available options.
*/
@available(iOS 7.0, *)
public class func performSystemAnimation(animation: UISystemAnimation, onViews views: [UIView], options: UIViewAnimationOptions, animations parallelAnimations: (() -> Void)?, completion: ((Bool) -> Void)?)
```

## 例

```swift:example
UIView.performSystemAnimation(UISystemAnimation.Delete,
                              onViews: [],
                              options: UIViewAnimationOptions(rawValue: 0),
                              animations: {
                                  aView.frame = CGRectMake(0,10,200,300)
     },
                              completion: nil)
```
あ、めっちゃ簡単やん。

第一と第二引数は何やねんという疑問ですが、`UISystemAnimation` は実質 `.Delete` しかありません。これを指定すると、第二引数で渡したビューに規定のアニメーションが適用され、終了時にビュー階層から削除される、というもののようです。見た目はブラーを伴った消滅アニメーションになります。
参考： http://mathewsanders.com/animations-in-swift-part-two/

本来の用途としてはこの消滅アニメーションだと思いますが、animations ブロックを利用して好きなプロパティにアニメーションを適用できるので、そちらの用途でも活用できます。

消滅アニメーションが不要であればとりあえず空配列でも渡しておけば良いでしょう。

# animateWithDuration:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion:

メソッド長すぎワロタ

おなじみのこのばねアニメーションでも同等のことができることがわかりました。各パラメーターを以下のようにするとシステムのアニメーションっぽくなります。ただし、これは決め打ちなので今後 OS のアップデートに追随できませんのでご注意ください。

`duration=0.5`, `delay=0.0`, `usingSpringWithDamping=1.0`, `initialSpringVelocity=0.0`

```swift
UIView.animateWithDuration(0.5,
                           delay: 0,
                           usingSpringWithDamping: 1.0,
                           initialSpringVelocity: 0,
                           options: UIViewAnimationOptions(rawValue: 0),
                           animations: {
                               …
                           },
                           completion: nil)
```

両者比較
![out.gif](https://qiita-image-store.s3.amazonaws.com/0/3603/f94c0eb3-3cec-351f-0ca3-b83e3310ad98.gif)


# むすび

`UIViewControllerAnimatedTransitioning` でカスタムトランジションを実装するといったとき、これらのメソッドが活躍することでしょう。オレオレアニメーションを実装したとしてもそのカーブがシステム標準っぽいだけでユーザーに安心感を与えられます。みなさんどんどん使っていきましょう。