ちょっと話題の記事

[iOS][Swift] UIKitをベンリにしてくれる Spring (4)

Spring

Springは、Meng Toさんが GitHub で公開されているライブラリです。Core Animation を使ったアニメーションや、View の周りの border の調整など UIKit のアレやコレを、カンタンにしてくれます。

今回は、ひとまず完結編として、これまでにご紹介したことを組み合わせて、少し複雑なアニメーションを実現してみます。

コレまでのシリーズについては以下を御覧ください。

[iOS][Swift] UIKitをベンリにしてくれる Spring (1) [iOS][Swift] UIKitをベンリにしてくれる Spring (2) [iOS][Swift] UIKitをベンリにしてくれる Spring (3)

今回のテーマ

今回は、花札をアニメーションさせてみようと思います。

準備

今回のデモを再現してみたい方は、[iOS][Swift] UIKitをベンリにしてくれる Spring (1) を参考に、Swift プロジェクトを作成後、Spring をプロジェクトに追加してください。

Storyboard

Storyboard

Storyboard 上に2枚の花札をおきました。ImageView を2つ配置し、Identity InspectorCustom Class で 各々 SpringImageView を指定しています。

また、花札画像を Attribute InspectorImage で指定しています。

assets

assets

今回は、これらの画像を使います。 ※一部画像は今回使用していません。

アニメーションの流れ

畳に置かれた花札の横に、もう一枚の花札を打ち付けると、置かれた花札が吹き飛び、最後に勝利のロゴが表示される流れです。

コーディング

今回は簡易なデモということで、viewDidLoad にサクッと書いていきます。

IBOutlet

@IBOutlet weak var leftCardSpringImageView: SpringImageView!
@IBOutlet weak var rightCardSpringImageView: SpringImageView!

victorySpringImageView

var victorySpringImageView = SpringImageView.new()
victorySpringImageView.image = UIImage(named: "youwin")
victorySpringImageView.frame = CGRectMake((self.view.frame.width - 300) / 2, (self.view.frame.height - 100) / 2, 300, 100)
victorySpringImageView.animation = "zoomIn"
victorySpringImageView.duration = 2
victorySpringImageView.alpha = 0
victorySpringImageView.delay = 1

勝利のロゴです。

花札と勝利ロゴなど、コンポーネント同士が重なって見難くなるのを防ぐため、 Storyboard で定義せず、一からコードで定義しています。

流れをざっと説明すると以下のとおりです。

  • SpringImageView 型の victorySpringImageView の生成
  • 画像を指定
  • 大きさと初期位置を指定
  • アニメーションの種類を "zoomIn" に指定
  • 動作時間は2秒
  • 最初は表示されないよう、alpha を 0 に設定
  • 1秒遅らせてアニメーション開始

花札

// アニメーションの種類を指定
self.leftCardSpringImageView.animation = "zoomIn"
self.rightCardSpringImageView.animation = "zoomOut"

// アニメーション時間の長さを指定
self.leftCardSpringImageView.duration = 2
self.rightCardSpringImageView.duration = 3

// view が 読み込まれてから少し間を置く
self.leftCardSpringImageView.delay = 1

花札 (leftCardSpringImageView, rightCardSpringImageView) について、各種指定をしています。

アニメーション実行

self.leftCardSpringImageView.animateNext { () -> () in
    self.rightCardSpringImageView.rotate = 0.1
    self.rightCardSpringImageView.x += 100
    self.rightCardSpringImageView.animateNext{ () -> () in
        self.leftCardSpringImageView.delay = 0
        self.leftCardSpringImageView.repeatCount = 3
        self.leftCardSpringImageView.animation = "morph"
        self.leftCardSpringImageView.animateNext({ () -> () in
            self.view.addSubview(victorySpringImageView)
            victorySpringImageView.animate()
            victorySpringImageView.alpha = 1
        })
    }
}

4つのアニメーションを連続して実行しています。

花札を畳に打ち付ける動き

左の花札のアニメーション(ズームイン)

吹き飛ばされる花札の動き

右の花札のアニメーション(右方向にズレながら、回転しつつズームアウト)

勝利して喜ぶ花札の動き

"morph" アニメーションを3回繰り返す

勝利のロゴが表示される動き

コード全体

import UIKit
import Spring

class ViewController: UIViewController {
    
    @IBOutlet weak var leftCardSpringImageView: SpringImageView!
    @IBOutlet weak var rightCardSpringImageView: SpringImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        var victorySpringImageView = SpringImageView.new()
        victorySpringImageView.image = UIImage(named: "youwin")
        victorySpringImageView.frame = CGRectMake((self.view.frame.width - 300) / 2, (self.view.frame.height - 100) / 2, 300, 100)
        victorySpringImageView.animation = "zoomIn"
        victorySpringImageView.duration = 2
        victorySpringImageView.alpha = 0
        victorySpringImageView.delay = 1
        
        // アニメーションの種類を指定
        self.leftCardSpringImageView.animation = "zoomIn"
        self.rightCardSpringImageView.animation = "zoomOut"
        
        // アニメーション時間の長さを指定
        self.leftCardSpringImageView.duration = 2
        self.rightCardSpringImageView.duration = 3
        
        // view が 読み込まれてから少し間を置く
        self.leftCardSpringImageView.delay = 1
        
        // 連続したアニメーション処理
        self.leftCardSpringImageView.animateNext { () -> () in
            self.rightCardSpringImageView.rotate = 0.1
            self.rightCardSpringImageView.x += 100
            self.rightCardSpringImageView.animateNext{ () -> () in
                self.leftCardSpringImageView.delay = 0
                self.leftCardSpringImageView.repeatCount = 3
                self.leftCardSpringImageView.animation = "morph"
                self.leftCardSpringImageView.animateNext({ () -> () in
                    self.view.addSubview(victorySpringImageView)
                    victorySpringImageView.animate()
                    victorySpringImageView.alpha = 1
                })
            }
        }
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

実行

こんなふうになりました!

まとめ

ここまで4回に渡って、Spring についてお届けしてきました。今回はゲームのサンプルのようなデモでしたが、様々な UIKit コンポーネントについて、ちょっとしたアニメーションをさせるだけでも、面白みが出て、他のアプリとの差別化が図れると思います。是非試してみてください。

クレジット

今回のブログでは、以下のサイトより画像を使わせて頂きました。ありがとうございます。

花札