Swiftでアニメーション[CoreAnimation編]

Swiftでアニメーションを実装する手順について、紹介していきます。

Swiftでアニメーションする方法として、UIKitのクラスメソッドをつかった方法とカスタム性の高いCoreAnimationクラスを使う方法があります。

今回は、CoreAnimationを使う方法を紹介します。

こちらも参考に


* [iOSアプリ初心者が覚えておきたい10のUIクラス](http://creatorhiro.com/archives/609)
* [売れるiOSアプリが作れるようになるおすすめの本８選](http://creatorhiro.com/archives/525)
* [SwiftでViewを操作する](http://qiita.com/web_chiro/items/7485cee8b73849f0c847)
* [SwiftでViewControllerを使う](http://qiita.com/h_nagami/items/66dc637463f98716bfa5)
* [Swiftでジェスチャーの追加](http://qiita.com/h_nagami/items/06a87514c49dd86c38ad)

##CoreAnimation

CoreAnimationは、UIKitアニメーションほど直感的ではなくアニメーションをプロパティの設定によって細かく設定できるようになっています。そのため、UIKitのときより難しい感じはありますが軽量かつ細かなアニメーションが可能になっています。

アニメーションを実装するための基本的なCoreAnimationクラスを２つ紹介します。

- CABasicAnimation
- CAAnimationGroup

###CABasicAnimation

CABasicAnimationクラスは、アニメーションで変化させるプロパティの変化前と後、インターバルを設定することでアニメーションさせるクラスです。

例えば、ビューの角丸サイズを変えるアニメーションはこのような感じです。

```swift
 func startCornerRadiusAnimation()
    {   
        // cornerRadiusを変更するアニメーション
        var cornerRadiusAnimation = CABasicAnimation(keyPath: "cornerRadius")
        
        // cornerRadius を 0 -> 100 に変化させるよう設定
        cornerRadiusAnimation.fromValue = 0
        cornerRadiusAnimation.toValue = 100
        
        // アニメーション
        cornerRadiusAnimation.duration = 2.0
        
        // アニメーションが終了した時の状態を維持する
        cornerRadiusAnimation.removedOnCompletion = false
        cornerRadiusAnimation.fillMode = kCAFillModeForwards
        
        // アニメーションが終了したらanimationDidStopを呼び出す
        cornerRadiusAnimation.delegate = self
        
        // アニメーションの追加
        animationView.layer.addAnimation(cornerRadiusAnimation, forKey: "cornerRadiusAnimation")
    }
```

![2015-06-08 05_37_43.gif](https://qiita-image-store.s3.amazonaws.com/0/35442/28c5fd89-9ab3-2c6d-22ce-0700f7475ff0.gif)


###CAAnimationGroup
CAAnimationGroupは、複数のアニメーションを同時に設定するためのクラスです。例えば、"ビューのサイズ変更・変形・回転を同時にアニメーションさせる"といったことができます。

```swift
func startCornerRadiusAndSizeAnimation()
    {
        // 角丸を変化させるアニメーション
        var cornerRadiusAnimation:CABasicAnimation = CABasicAnimation(keyPath: "cornerRadius")
        cornerRadiusAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
        cornerRadiusAnimation.fromValue = 0
        cornerRadiusAnimation.toValue = 150
        
        // サイズを変化させるアニメーション
        var sizeAnimation:CABasicAnimation = CABasicAnimation(keyPath: "bounds.size")
        sizeAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
        sizeAnimation.fromValue = NSValue(CGSize:CGSizeMake(100, 100))
        sizeAnimation.toValue = NSValue(CGSize:CGSizeMake(300, 300))
        
        // 角丸アニメーションとサイズアニメーションをグループとして登録
        var animationGroup:CAAnimationGroup = CAAnimationGroup()
        animationGroup.setValue("group-animation1", forKey: "animationName")
        animationGroup.animations = [cornerRadiusAnimation, sizeAnimation]
        animationGroup.duration = 2.0
        animationGroup.delegate = self
        
        // アニメーションが終了した時の状態を維持する
        animationGroup.removedOnCompletion = false
        animationGroup.fillMode = kCAFillModeForwards
        
        // アニメーショングループの追加
        animationView.layer.addAnimation(animationGroup, forKey: "group-animation")
    }
```

![swift-animation-coreAnimation-cornerRadiusAndSize.gif](https://qiita-image-store.s3.amazonaws.com/0/35442/3e44e59c-4c03-8370-1962-a8288780debf.gif)




そのほかにもCoreAnimationクラスがいくつかあります。

- CAPropetyAnimation
- CATransition
- CGAffineTransform

##最後に

CoreAnimationクラスを使ったアニメーションでは、UIKitクラスで提供されているアニメーションではできない *layerプロパティ* のアニメーションといった細かな動作をさせることができます。

また複数のアニメーションを同時にさせることや、実装するアニメーションが多い場合にコードを整理させて書くこともできます。