この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
今回はSwift版のkeyframeアニメーション作れるRazzleDazzleというライブラリの簡単な使い方をご紹介したいと思います。 RazzleDazzleはJazzHandsというOvjective-Cのキーフレームアニメーション作れるライブラリのSwfit版になります。
キーフレームアニメーションといっても、どんなことが出来るのかイメージがわかない方はGithubページのデモGIFを見ると判りやすいです。 https://github.com/IFTTT/RazzleDazzle
今回は基本的な使い方をマスターするために、下記のような簡単なウォークスルーページを作りたいと思います。
開発環境
また、今回の開発環境は下記で実施しています。
Xcode | 7.3.1 |
---|---|
Swift | 2.2 |
CocoaPods | 1.0.0 |
ターゲットはiOS8.1、デバイスはiPhone、画面回転無しでProjectを作成しました。
導入
CocoaPodsで追加します。
use_frameworks!
target "ターゲット名" do
pod 'RazzleDazzle'
end
実装
対象のViewControllerに対して
import RazzleDazzle
を追加して、
UIViewController
を
AnimatedPagingScrollViewController
に変更します。
ViewController.swift
import UIKit
import RazzleDazzle
class ViewController: AnimatedPagingScrollViewController {
AnimatedPagingScrollViewControllerはウォークスルーなどでよく見かける横にスクロールするUIScrollViewが用意されています。
ページ数の設定
スクロールのページ数の設定をします。今回は3ページとしました。下記コードを追加します。
ViewController.swift
// ページ数
override func numberOfPages() -> Int {
return 3
}
ページとアニメーションの関係
RazzleDazzleのアニメーションはUIScrollViewの位置で変化を定義します。画面の左上の位置が基準になります。 スクロールの位置 = タイムライン のイメージです。
1ページ目を表示する時は0、2ページ目は1になります。0より大きく1未満の数字は1ページ目から2ページに遷移する途中の状態です。
背景色のアニメーション
まず最初に背景色を変更します。
ViewController.swift
override func viewDidLoad() {
super.viewDidLoad()
configureAnimations()
}
// アニメーションを設定する
private func configureAnimations() {
configureScrollView()
}
private func configureScrollView() {
// 背景色のアニメーション
let backgroundColorAnimation = BackgroundColorAnimation(view: scrollView)
backgroundColorAnimation[-1] = UIColor.greenColor()
backgroundColorAnimation[0] = UIColor.grayColor()
backgroundColorAnimation[1] = UIColor.yellowColor()
backgroundColorAnimation[1.3] = UIColor.brownColor()
backgroundColorAnimation[2] = UIColor.redColor()
backgroundColorAnimation[3] = UIColor.blueColor()
animator.addAnimation(backgroundColorAnimation)
}
let backgroundColorAnimation = BackgroundColorAnimation(view: scrollView)
で、scrollViewの背景アニメーションを作成します。
backgroundColorAnimation[0] = UIColor.grayColor()
これはは0の位置の時に灰色にするという定義です。今回は各ページ毎に色を変えてますが、背景色を変更するタイミングだけ定義すればOKです。
animator.addAnimation(backgroundColorAnimation)
で背景色の変更のアニメーションを登録します。
上記のサンプルコードの挙動は
1ページ目 :灰色
2ページ目 :黄色
3ページ目 :赤
2ページ目から3ページになる時に一旦茶色になってから変わる
1ページ目で左にスクロールしようとすると黄緑っぽい色になる
3ページ目で右にスクロールしようとすると青(紫?)っぽい色になる
となります。
パーツの配置
コード上で画像など配置するコンポーネントを追加していきます。
今回はそれぞれのページにテキスト用とイメージ用の画像を用意しました。
サンプルで利用している画像は下記からお借りしています。
http://flat-icon-design.com/
ViewController.swift
private let page1ImageView = UIImageView(image: UIImage(named: "page1"))
private let page2ImageView = UIImageView(image: UIImage(named: "page2"))
private let page3ImageView = UIImageView(image: UIImage(named: "page3"))
private let text1ImageView = UIImageView(image: UIImage(named: "text1"))
private let text2ImageView = UIImageView(image: UIImage(named: "text2"))
private let text3ImageView = UIImageView(image: UIImage(named: "text3"))
// ページ数
override func numberOfPages() -> Int {
return 3
}
override func viewDidLoad() {
super.viewDidLoad()
configureViews()
configureAnimations()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// 画面にパーツを配置する
private func configureViews () {
contentView.addSubview(page1ImageView)
contentView.addSubview(page2ImageView)
contentView.addSubview(page3ImageView)
contentView.addSubview(text1ImageView)
contentView.addSubview(text2ImageView)
contentView.addSubview(text3ImageView)
}
contentView
に対して
addSubview
します。
この状態で実行すると、下図のように最初のページに固まってしまうので、表示するページの設定と制約等をつけます。
ページ指定と制約
ViewController.swift
// アニメーションを設定する
private func configureAnimations() {
configureScrollView()
configurePage1()
configurePage2()
configurePage3()
}
private func configurePage1() {
contentView.addConstraint(NSLayoutConstraint(item: page1ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 0.65, constant: 0))
contentView.addConstraint(NSLayoutConstraint(item: text1ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 1.65, constant: 0))
keepView(page1ImageView, onPage: 0)
keepView(text1ImageView, onPage: 0)
}
private func configurePage2() {
contentView.addConstraint(NSLayoutConstraint(item: page2ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 0.65, constant: 0))
contentView.addConstraint(NSLayoutConstraint(item: text2ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 1.65, constant: 0))
keepView(page2ImageView, onPage: 1)
keepView(text2ImageView, onPage: 1)
}
private func configurePage3() {
contentView.addConstraint(NSLayoutConstraint(item: page3ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 0.65, constant: 0))
contentView.addConstraint(NSLayoutConstraint(item: text3ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 1.65, constant: 0))
keepView(page3ImageView, onPage: 2)
keepView(text3ImageView, onPage: 2)
}
NSLayoutConstraintを使い位置を設定します。今回は上半分にイメージ画像、下半分にテキストの画像の簡単な構成なので、制約の内容は各ページ同じです。
keepView
でどのページに表示するかを定義します。
keepView(page1ImageView, onPage: 0)
は
page1ImageView
を最初のページ(左上が0)に表示します。
上記コードを実行すると以下の様な感じになります。
※ 一部背景色がどぎつい感じだったので変更してます
keepView の onPageについて
onPageに設定した値は正確にはX座標の中心点になります。keepView(page1ImageView, onPage: 0)の 0の部分を0.5に変更すると、 次のページとの中間部分が中心点になります。
フェードのアニメーションを入れる
keepView(page1ImageView, onPage: 0)
を
keepView(page1ImageView, onPages: [0, 1], atTimes: [0, 1])
に書き換えます。
onPagesは複数のページにまたがって表示したい時に配列で定義します。
atTimesはその配置するフレームを定義します。
上記のコードに変更して実行すると以下の挙動になります。
2ページ目の時も1ページ目の画像が残るようになりました。
次に2ページ目になるにつれ、画像がフェードアウトになるようにアニメーションを追加します。
ViewController.swift
private func configurePage1() {
contentView.addConstraint(NSLayoutConstraint(item: page1ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 0.65, constant: 0))
contentView.addConstraint(NSLayoutConstraint(item: text1ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 1.65, constant: 0))
keepView(page1ImageView, onPages: [0, 1], atTimes: [0, 1])
keepView(text1ImageView, onPage: 0)
let alphaAnimation = AlphaAnimation(view: page1ImageView)
alphaAnimation[0] = 1
alphaAnimation[1] = 0
animator.addAnimation(alphaAnimation)
}
AlphaAnimationを使うと透明度を変更することが出来ます。
alphaAnimation[0] = 1
上記コードは左上の位置が0(1ページ)の時はアルファ値が1、
alphaAnimation[1] = 0
左上の位置が1(2ページ)の時がアルファ値が0になるアニメーションになります。
同じように2ページめと3ページ目のイメージのアニメーションを修正します。
下記は今回の最終版のコードになります。
ViewController.swift
import UIKit
import RazzleDazzle
class ViewController: AnimatedPagingScrollViewController {
private let page1ImageView = UIImageView(image: UIImage(named: "page1"))
private let page2ImageView = UIImageView(image: UIImage(named: "page2"))
private let page3ImageView = UIImageView(image: UIImage(named: "page3"))
private let text1ImageView = UIImageView(image: UIImage(named: "text1"))
private let text2ImageView = UIImageView(image: UIImage(named: "text2"))
private let text3ImageView = UIImageView(image: UIImage(named: "text3"))
// ページ数
override func numberOfPages() -> Int {
return 3
}
override func viewDidLoad() {
super.viewDidLoad()
configureViews()
configureAnimations()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// 画面にパーツを配置する
private func configureViews () {
contentView.addSubview(page1ImageView)
contentView.addSubview(page2ImageView)
contentView.addSubview(page3ImageView)
contentView.addSubview(text1ImageView)
contentView.addSubview(text2ImageView)
contentView.addSubview(text3ImageView)
}
// アニメーションを設定する
private func configureAnimations() {
configureScrollView()
configurePage1()
configurePage2()
configurePage3()
}
private func configureScrollView() {
// 背景色のアニメーション
let backgroundColorAnimation = BackgroundColorAnimation(view: scrollView)
backgroundColorAnimation[-1] = UIColor.greenColor()
backgroundColorAnimation[0] = UIColor.lightGrayColor()
backgroundColorAnimation[1] = UIColor.yellowColor()
backgroundColorAnimation[1.3] = UIColor.brownColor()
backgroundColorAnimation[2] = UIColor.orangeColor()
backgroundColorAnimation[3] = UIColor.blueColor()
animator.addAnimation(backgroundColorAnimation)
}
private func configurePage1() {
contentView.addConstraint(NSLayoutConstraint(item: page1ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 0.65, constant: 0))
contentView.addConstraint(NSLayoutConstraint(item: text1ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 1.65, constant: 0))
keepView(page1ImageView, onPages: [0, 1], atTimes: [0, 1])
keepView(text1ImageView, onPage: 0)
let alphaAnimation = AlphaAnimation(view: page1ImageView)
alphaAnimation[0] = 1
alphaAnimation[1] = 0
animator.addAnimation(alphaAnimation)
}
private func configurePage2() {
contentView.addConstraint(NSLayoutConstraint(item: page2ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 0.65, constant: 0))
contentView.addConstraint(NSLayoutConstraint(item: text2ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 1.65, constant: 0))
keepView(page2ImageView, onPages: [0, 1, 2], atTimes: [0, 1, 2])
keepView(text2ImageView, onPage: 1)
let alphaAnimation = AlphaAnimation(view: page2ImageView)
alphaAnimation[0] = 0
alphaAnimation[1] = 1
alphaAnimation[2] = 0
animator.addAnimation(alphaAnimation)
}
private func configurePage3() {
contentView.addConstraint(NSLayoutConstraint(item: page3ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 0.65, constant: 0))
contentView.addConstraint(NSLayoutConstraint(item: text3ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 1.65, constant: 0))
keepView(page3ImageView, onPages: [1, 2], atTimes: [1, 2])
keepView(text3ImageView, onPage: 2)
let alphaAnimation = AlphaAnimation(view: page3ImageView)
alphaAnimation[1] = 0
alphaAnimation[2] = 1
animator.addAnimation(alphaAnimation)
}
}
さいごに
今回は単純にbackgroundColorとalphaしか使いませんでしたが、他にも色々なプロパティのアニメーションをすることが出来ます。 色々と試してみると楽しいかもしれません。