実践 Swift UIViewアニメーション PART I
こんにちは、最近ずっと Swift で iPhone のアプリを作ってる渡部です。
まだまだ分からない事が色々でてきて中々面白いです。
iPhoneのアプリを作っているとよく出てくるのが、UIViewのアニメーション。
対象Viewの移動や縮小・拡大をする際にアニメーションさせると、一気にいい感じのアプリになります。
UIViewのアニメーション関連のメッソッドは下記の7種類あります。
【アニメーション】
1. UIView.animateWithDuration
【トランジション】
2. UIView.transitionWithView
3. UIView.transitionFromView
【キーフレームアニメーション】
4. UIView.animateKeyframesWithDuration
5. UIView.addKeyframeWithRelativeStartTime
【その他】
6. UIView.performSystemAnimation
7. UIView.performWithoutAnimation
今回のPART Iでは1の「UIView.animateWithDuration」を取り上げます。
PART I I 以降で、トランジション、キーフレームアニメーション、その他のアニメーション機能を、取り上げたいと思います。
環境は、Xcode6.2を使用しています。
<目次>
UIView.animateWithDurationで作るアニメーションまとめ
1.基本を理解
UIView.animateWithDurationでアニメーションを行う場合の基礎です。
具体的にアニメーションを考えてみましょう!
例としてボタンをクリックされた時に、UIViewで作ったボックスを左から右へ動かしてみます。
ソースはこんな感じで記述しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
import UIKit class ViewController: UIViewController { var moveView: UIView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. // アニメーション用のビュー self.moveView = UIView(frame: CGRectMake(0, UIScreen.mainScreen().bounds.height / 2, 10, 10)) self.moveView.backgroundColor = UIColor.greenColor() self.view.addSubview(self.moveView) // アニメーションなし let btn1 = UIButton(frame: CGRectMake(0, 10, 100, 50)) btn1.backgroundColor = UIColor.orangeColor() btn1.setTitle("move", forState: UIControlState.Normal) btn1.setTitleColor(UIColor.grayColor(), forState: UIControlState.Highlighted) btn1.addTarget(self, action: "onNoAnimationClick:", forControlEvents: .TouchUpInside) self.view.addSubview(btn1) } // アニメーションなし func onNoAnimationClick(sender: AnyObject!) { self.moveView.frame.origin.x = UIScreen.mainScreen().bounds.width - 10 } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } |
実行するとこうなります。
ボタンを押下したタイミングで左側にあったボックスが消えて、瞬時に右側に表示されます。
これをアニメーションありで作ると、こうなります。
ボックスが左から右へスーっと移動してますね。
ソースは下記の様になり、先ほどのアニメーションなしと比べて、ボタンクリックアクションメソッド部分に、「UIView.animateWithDuration」メソッドを追加しただけです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
import UIKit class ViewController: UIViewController { var moveView: UIView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. // アニメーション用のビュー self.moveView = UIView(frame: CGRectMake(0, UIScreen.mainScreen().bounds.height / 2, 10, 10)) self.moveView.backgroundColor = UIColor.greenColor() self.view.addSubview(self.moveView) // アニメーション1 let btn2 = UIButton(frame: CGRectMake(110, 10, 100, 50)) btn2.backgroundColor = UIColor.orangeColor() btn2.setTitle("Animation1", forState: UIControlState.Normal) btn2.setTitleColor(UIColor.grayColor(), forState: UIControlState.Highlighted) btn2.addTarget(self, action: "onAnimation1Click:", forControlEvents: .TouchUpInside) self.view.addSubview(btn2) } // 1.のパターンのアニメーション func onAnimation1Click(sender: AnyObject!) { UIView.animateWithDuration(1, // アニメーションの時間 animations: {() -> Void in // アニメーションする処理 self.moveView.frame.origin.x = UIScreen.mainScreen().bounds.width - 10 }) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } |
UIView.animateWithDurationメソッドは、事前に定義された状態から、animationsで定義したクロージャ内で指定された状態へ遷移させ、その遷移してる事を分かるようにアニメーションするメソッドです。
その移動中の動作で、色々なオプションがあり、そのオプションや移動前・移動後の動作によってメソッドの引数が異なります。
また、UIView.animateWithDurationメソッドは、非同期で行われるため、アニメーション後に処理を行いたい場合は、completionが定義されているUIView.animateWithDurationを選択して下さい。
2.UIView.animateWithDurationの定義
UIView.animateWithDurationの定義は次の4つがあります。
1.UIView.animateWithDuration(duration, animations)メソッド
基本シンプルなアニメーション表示です。
1 2 3 4 5 |
UIView.animateWithDuration( duration: NSTimeInterval, // アニメーションの時間 animations: {() -> Void in // アニメーションする処理 }) |
duration:アニメーションの時間を設定します。(秒単位)
animations:クロージャ内に最終的な表示結果を記述します。
例:Animation1ボタンを押下したら、左側にある緑のボックスが右端へ移動します。
サンプルソース:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
import UIKit class ViewController: UIViewController { var moveView: UIView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. // アニメーション用のビュー self.moveView = UIView(frame: CGRectMake(0, UIScreen.mainScreen().bounds.height / 2, 10, 10)) self.moveView.backgroundColor = UIColor.greenColor() self.view.addSubview(self.moveView) // アニメーション1 let btn2 = UIButton(frame: CGRectMake(110, 10, 100, 50)) btn2.backgroundColor = UIColor.orangeColor() btn2.setTitle("Animation1", forState: UIControlState.Normal) btn2.setTitleColor(UIColor.grayColor(), forState: UIControlState.Highlighted) btn2.addTarget(self, action: "onAnimation1Click:", forControlEvents: .TouchUpInside) self.view.addSubview(btn2) } // 1.のパターンのアニメーション func onAnimation1Click(sender: AnyObject!) { UIView.animateWithDuration(1, // アニメーションの時間 animations: {() -> Void in // アニメーションする処理 self.moveView.frame.origin.x = UIScreen.mainScreen().bounds.width - 10 }) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } |
実行:
2.UIView.animateWithDuration(duration, animations, completion)メソッド
1 2 3 4 5 6 7 8 |
UIView.animateWithDuration( duration: NSTimeInterval, // アニメーションの時間 animations: {() -> Void in // アニメーションする処理 } , completion: {(Bool) -> Void in // アニメーション終了後の処理 }) |
duration:アニメーションの時間を設定します。(秒単位)
animations:クロージャ内に最終的な表示結果を記述します。
completion:クロージャー内にアニメーション終了後に行う処理を記述します。
例:Animation2ボタンを押下したら、左側にある緑のボックスが右端へ移動し、移動後に緑のボックスが赤になります。
サンプルサンプルソース:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
import UIKit class ViewController: UIViewController { var moveView: UIView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. // アニメーション用のビュー self.moveView = UIView(frame: CGRectMake(0, UIScreen.mainScreen().bounds.height / 2, 10, 10)) self.moveView.backgroundColor = UIColor.greenColor() self.view.addSubview(self.moveView) // アニメーション2 let btn3 = UIButton(frame: CGRectMake(220, 10, 100, 50)) btn3.backgroundColor = UIColor.orangeColor() btn3.setTitle("Animation2", forState: UIControlState.Normal) btn3.setTitleColor(UIColor.grayColor(), forState: UIControlState.Highlighted) btn3.addTarget(self, action: "onAnimation2Click:", forControlEvents: .TouchUpInside) self.view.addSubview(btn3) } // 2.のパターンのアニメーション func onAnimation2Click(sender: AnyObject!) { UIView.animateWithDuration(1, // アニメーションの時間 animations: {() -> Void in // アニメーションする処理 self.moveView.frame.origin.x = UIScreen.mainScreen().bounds.width - 10 }, completion: {(finished: Bool) -> Void in // アニメーション終了後の処理 self.moveView.backgroundColor = UIColor.redColor() }) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } |
実行:
3.UIView.animateWithDuration(duration, delay, options , animations, completion)メソッド
1 2 3 4 5 6 7 8 9 10 |
UIView.animateWithDuration( duration: NSTimeInterval, // アニメーションの時間 delay: NSTimeInterval, // アニメーションの遅延時間 options: UIViewAnimationOptions, // アニメーションの加速・減速などのオプション animations: {() -> Void in // アニメーションする処理 } , completion: {(Bool) -> Void in // アニメーション終了後の処理 }) |
duration:アニメーションの時間を設定します。(秒単位)
delay:アニメーション開始までの遅延時間を設定します。(秒単位)
options:速度変化のオプションを指定します。詳しくはoptions効果を参考にして下さい。
animations:クロージャ内に最終的な表示結果を記述します。
completion:クロージャー内にアニメーション終了後に行う処理を記述します。
例:Animation3ボタンを押下したら、左側にある緑のボックスが0.5秒後に最初に加速して右端へ移動し、移動後に緑のボックスが赤になります。
サンプルソース:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
import UIKit class ViewController: UIViewController { var moveView: UIView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. // アニメーション用のビュー self.moveView = UIView(frame: CGRectMake(0, UIScreen.mainScreen().bounds.height / 2, 10, 10)) self.moveView.backgroundColor = UIColor.greenColor() self.view.addSubview(self.moveView) // アニメーション3 let btn4 = UIButton(frame: CGRectMake(0, 70, 100, 50)) btn4.backgroundColor = UIColor.orangeColor() btn4.setTitle("Animation3", forState: UIControlState.Normal) btn4.setTitleColor(UIColor.grayColor(), forState: UIControlState.Highlighted) btn4.addTarget(self, action: "onAnimation3Click:", forControlEvents: .TouchUpInside) self.view.addSubview(btn4) } // 3.のパターンのアニメーション func onAnimation3Click(sender: AnyObject!) { UIView.animateWithDuration(1, // アニメーションの時間 delay: 0.5, // アニメーションの遅延時間 options: UIViewAnimationOptions.CurveEaseIn, // 速度の変化オプション animations: {() -> Void in // アニメーションする処理 self.moveView.frame.origin.x = UIScreen.mainScreen().bounds.width - 10 }, completion: {(finished: Bool) -> Void in // アニメーション終了後の処理 self.moveView.backgroundColor = UIColor.redColor() }) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } |
実行:
4.UIView.animateWithDuration(duration, delay, usingSpringWithDamping, initialSpringVelocity, options , animations, completion)メソッド
1 2 3 4 5 6 7 8 9 10 11 12 |
UIView.animateWithDuration( duration: NSTimeInterval, // アニメーションの時間 delay: NSTimeInterval, // アニメーションの遅延時間 usingSpringWithDamping: CGFloat, // アニメーションの終端で、バネのようなアニメーションになります。 initialSpringVelocity: CGFloat, // バネの初速です options: UIViewAnimationOptions, // アニメーションの加速・減速などのオプション animations: {() -> Void in // アニメーションする処理 } , completion: {(Bool) -> Void in // アニメーション終了後の処理 }) |
duration:アニメーションの時間を設定します。(秒単位)
delay:アニメーション開始までの遅延時間を設定します。(秒単位)
usingSpringWithDamping:スプリングの効果(0..1)
initialSpringVelocity:スプリングの初速(0..1)
options:速度変化のオプションを指定します。詳しくはoptions効果を参考にして下さい。
animations:クロージャ内に最終的な表示結果を記述します。
completion:クロージャー内にアニメーション終了後に行う処理を記述します。
例:Animation4ボタンを押下したら、左側にある緑のボックスが0.5秒後に最初に加速して右端へ移動し、右端でスプリングエフェクを実行し、実行後に緑のボックスが赤になります。
サンプルソース:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
import UIKit class ViewController: UIViewController { var moveView: UIView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. // アニメーション用のビュー self.moveView = UIView(frame: CGRectMake(0, UIScreen.mainScreen().bounds.height / 2, 10, 10)) self.moveView.backgroundColor = UIColor.greenColor() self.view.addSubview(self.moveView) // アニメーション4 let btn5 = UIButton(frame: CGRectMake(110, 70, 100, 50)) btn5.backgroundColor = UIColor.orangeColor() btn5.setTitle("Animation4", forState: UIControlState.Normal) btn5.setTitleColor(UIColor.grayColor(), forState: UIControlState.Highlighted) btn5.addTarget(self, action: "onAnimation4Click:", forControlEvents: .TouchUpInside) self.view.addSubview(btn5) } // 4.のパターンのアニメーション func onAnimation4Click(sender: AnyObject!) { UIView.animateWithDuration(1, // アニメーションの時間 delay: 0.5, // アニメーションの遅延時間 usingSpringWithDamping: 0.5, // スプリングの効果(0..1) initialSpringVelocity: 0.5, // バネの初速。(0..1) options: UIViewAnimationOptions.CurveEaseIn, animations: {() -> Void in // アニメーションする処理 self.moveView.frame.origin.x = UIScreen.mainScreen().bounds.width - 10 }, completion: {(finished: Bool) -> Void in // アニメーション終了後の処理 self.moveView.backgroundColor = UIColor.redColor() }) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } |
実行:
3.options効果
optionsで、指定可能なオプションは下記の22種類があり、指定することでアニメーションに様々な効果を与える事が出来ます。
また、今回の「UIView.animateWithDuration」では、効果が出るものに「◯」を付けています。(なお、効果が出ないものを指定してもエラーにはなりません)
ちょっと今回は効果がわからなかったものには「?」をつけてあります。
次回のPARTIIまでには調べて、アップデートします。(すいません)
# | 指定可能オプション | 効果の有無 | 効果 |
レイアウトオプション | |||
1 | UIViewAnimationOptions.LayoutSubviews | ? | 親ビューと一緒にアニメーションするように、コミット時にサブビューを配置します。(※) |
2 | UIViewAnimationOptions.AllowUserInteraction | - | アニメーションしているビューに対して、ユーザ操作を受け取ることが出来ます。UIView.animateWithDurationで使用する意味がちょっと見出せなかった。トランジションメソッドでは、効果がわかりやすい。 |
3 | UIViewAnimationOptions.BeginFromCurrentState | ◯ | アニメーションの最中に割り込みで別のアニメーションが発生した場合に、最初に実行したアニメーションが割り込みした直後の状態から、割り込みした状態後の状態へアニメーションを行う。 |
4 | UIViewAnimationOptions.Repeat | ◯ | アニメーションを無限に繰り返す。 |
5 | UIViewAnimationOptions.Autoreverse | ◯ | animationsで指定された状態までのアニメーションを実施し、一度だけ元の状態(アニメーション前)に戻るアニメーションを実施後、アニメーションなしでanimationsで指定された状態になる。 |
6 | UIViewAnimationOptions.OverrideInheritedDuration | ◯ | 直前のアニメーションの時間をキャンセルし、指定した時間でアニメーションを実施します。 |
7 | UIViewAnimationOptions.OverrideInheritedCurve | ◯ | 直前のアニメーションの曲線の値をキャセルし、指定した曲線の値でアニメーションを実施します。 |
8 | UIViewAnimationOptions.AllowAnimatedContent | - | アニメーション中にanimationsで指定したプロパティの影響を受けます。UIView.animateWithDurationで使用する意味がちょっと見出せなかった。トランジションメソッドでは、効果がわかりやすい。 |
9 | UIViewAnimationOptions.ShowHideTransitionViews | - | トランジションメソッドで使用します。遷移する際に非表示にします。 |
10 | UIViewAnimationOptions.OverrideInheritedOptions | ? | 直前のアニメーションオプションを継承しない。(※) |
タイミング曲線のオプション | |||
11 | UIViewAnimationOptions.CurveEaseInOut | ◯ | ゆっくり始まり、一定の速度で進み、ゆっくり終わる。(デフォルト) |
12 | UIViewAnimationOptions.CurveEaseIn | ◯ | ゆっくり始まり、後は一定の速度で進む |
13 | UIViewAnimationOptions.CurveEaseOut | ◯ | 一定の速度で進み、 ゆっくり終わる |
14 | UIViewAnimationOptions.CurveLinear | ◯ | 一定の速度で進む |
トランジションのオプション | |||
15 | UIViewAnimationOptions.TransitionNone | - | トランジションメソッドで使用します。何もしません。(デフォルト) |
16 | UIViewAnimationOptions.TransitionFlipFromLeft | - | トランジションメソッドで使用します。左辺が手前に回って右辺になるようなアニメーションです。 |
17 | UIViewAnimationOptions.TransitionFlipFromRight | - | トランジションメソッドで使用します。左辺が背後に回って右辺になるようなアニメーションです。 |
18 | UIViewAnimationOptions.TransitionCurlUp | - | トランジションメソッドで使用します。ページをめくり上げる様なアニメーションです。 |
19 | UIViewAnimationOptions.TransitionCurlDown | - | トランジションメソッドで使用します。TransitionCurlUpの逆のアニメーションです。 |
20 | UIViewAnimationOptions.TransitionCrossDissolve | - | トランジションメソッドで使用します。クロスディゾルブ、じわっと現れるようなアニメーションです。 |
21 | UIViewAnimationOptions.TransitionFlipFromTop | - | トランジションメソッドで使用します。上底が背後に回って下底になる様なアニメーションです。 |
22 | UIViewAnimationOptions.TransitionFlipFromBottom | - | トランジションメソッドで使用します。上底が手前に回って下底になる様なアニメーションです。 |
それぞれのオプションを指定した場合のアニメーション例を以下に紹介します。
(サンプルとして、「UIView.animateWithDuration」メソッドで使用出来ないものも載せています)
1.UIViewAnimationOptions.LayoutSubviews
※調査中
2.UIViewAnimationOptions.AllowUserInteraction
アニメーションしているビューに対して、ユーザ操作を受け取ることが出来ます。
サンプルソース:
UITapGestureRecognizerで、タップイベントをアニメーションするViewのmoveViewに登録する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "onTap:") self.moveView.addGestureRecognizer(tap) var opt: UIViewAnimationOptions = UIViewAnimationOptions.allZeros if (!isAnimation) { opt = UIViewAnimationOptions.TransitionCurlDown } else { opt = UIViewAnimationOptions.TransitionCurlDown | UIViewAnimationOptions.AllowUserInteraction } UIView.transitionWithView( self.moveView, // 対象のビュー duration: 5, // アニメーションの時間 options: opt, // アニメーション変化オプション animations: {() -> Void in // アニメーションする処理 self.moveView.backgroundColor = UIColor.redColor() }, completion: {(finished: Bool) -> Void in // アニメーション終了後の処理 }) |
タップイベント:
1 2 3 4 5 |
func onTap(sender: UITapGestureRecognizer) { let formatter = NSDateFormatter() formatter.dateFormat = "yyyy/MM/dd HH:mm:ss" println("onTap:\(formatter.stringFromDate(NSDate()))") } |
実行例:
サンプルでは画面だけですので、わかりにくいですが、サンプルのアニメーション中に対象のViewをタップしています。
デバッグ環境で実行すれば、ログ出力を確認出来ます。
実行結果のログ:
3.UIViewAnimationOptions.BeginFromCurrentState
アニメーションの最中に割り込みで別のアニメーションが発生した場合に、最初に実行したアニメーションが割り込みした直後の状態から、割り込みした状態後の状態へアニメーションを行う。
サンプルソース:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
UIView.animateWithDuration( 3, // アニメーションの時間 delay: 0, // アニメーションの遅延時間 options: UIViewAnimationOptions.CurveEaseInOut, // アニメーションの変化オプション animations: {() -> Void in // アニメーションする処理 self.moveView.frame.origin.x = self.containerView.frame.width - self.moveView.frame.width self.moveView.backgroundColor = UIColor.blueColor() }, completion: {(finished: Bool) -> Void in }) var opt: UIViewAnimationOptions = UIViewAnimationOptions.allZeros if (!isAnimation) { opt = UIViewAnimationOptions.CurveEaseInOut } else { opt = UIViewAnimationOptions.CurveEaseInOut | UIViewAnimationOptions.BeginFromCurrentState } self.moveView.backgroundColor = UIColor.yellowColor() UIView.animateWithDuration( 2, // アニメーションの時間 delay: 0, // アニメーションの遅延時間 options: opt, // アニメーションの変化オプション animations: {() -> Void in // アニメーションする処理 self.moveView.frame.origin.x = self.containerView.frame.width / 2 self.moveView.backgroundColor = UIColor.redColor() }, completion: {(finished: Bool) -> Void in // アニメーション終了後の処理 }) |
実行例:
Optionなしでは、最初のアニメーションの後に実行している。四角形を黄色にする処理の後に、次のアニメーションが処理されるため、一瞬黄色になりますが、Optionありでは、最初のアニメーション中に次のアニメーションが実行されるため、黄色になる処理がキャンセルされます。
Optionなし
Optionあり
4.UIViewAnimationOptions.Repeat
アニメーションを無限に繰り返す。
サンプルソース:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
self.moveView.frame.origin.x = 0 var opt: UIViewAnimationOptions = UIViewAnimationOptions.allZeros if (isAnimation) { opt = UIViewAnimationOptions.Repeat } UIView.animateWithDuration( 1, // アニメーションの時間 delay: 0.5, // アニメーションの遅延時間 options: opt, // アニメーションの変化オプション animations: {() -> Void in // アニメーションする処理 self.moveView.frame.origin.x = self.containerView.frame.width - self.moveView.frame.width self.moveView.backgroundColor = UIColor.redColor() }, completion: {(finished: Bool) -> Void in // アニメーション終了後の処理 }) |
実行例:
実行すると四角形が左から右へのアニメーションを延々と繰り返します。
5.UIViewAnimationOptions.Autoreverse
animationsで指定された状態までのアニメーションを実施し、一度だけ元の状態(アニメーション前)に戻るアニメーションを実施後、アニメーションなしでanimationsで指定された状態になる。
サンプルソース:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
self.moveView.frame.origin.x = 0 var opt: UIViewAnimationOptions = UIViewAnimationOptions.allZeros if (isAnimation) { opt = UIViewAnimationOptions.Autoreverse } UIView.animateWithDuration( 3, // アニメーションの時間 delay: 0.5, // アニメーションの遅延時間 options: opt, // アニメーションの変化オプション animations: {() -> Void in // アニメーションする処理 self.moveView.frame.origin.x = self.containerView.frame.width - self.moveView.frame.width self.moveView.backgroundColor = UIColor.redColor() }, completion: {(finished: Bool) -> Void in // アニメーション終了後の処理 }) |
実行例:
6.UIViewAnimationOptions.OverrideInheritedDuration
直前のアニメーションの時間をキャンセルし、指定した時間でアニメーションを実施します。
サンプルソース:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
let formatter = NSDateFormatter() formatter.dateFormat = "yyyy/MM/dd HH:mm:ss" println("1:\(formatter.stringFromDate(NSDate()))") self.moveView.frame.origin.x = self.containerView.frame.width / 2 UIView.animateWithDuration( 1, // アニメーションの時間 delay: 0.5, // アニメーションの遅延時間 options: UIViewAnimationOptions.CurveEaseInOut, // アニメーションの変化オプション animations: {() -> Void in // アニメーションする処理 self.moveView.frame.origin.x = self.containerView.frame.height / 3 * 2 self.moveView.frame.origin.y = 0 self.moveView.backgroundColor = UIColor.redColor() var opt: UIViewAnimationOptions = UIViewAnimationOptions.allZeros if (!isAnimation) { opt = UIViewAnimationOptions.CurveEaseOut } else { opt = UIViewAnimationOptions.CurveEaseOut | UIViewAnimationOptions.OverrideInheritedDuration } UIView.animateWithDuration( 2, // アニメーションの時間 delay: 0.5, // アニメーションの遅延時間 options: opt, // アニメーションの変化オプション animations: {() -> Void in // アニメーションする処理 self.moveView.frame.origin.x = self.containerView.frame.width / 2 - self.moveView.frame.width / 2 self.moveView.frame.origin.y = self.containerView.frame.height - self.moveView.frame.height self.moveView.backgroundColor = UIColor.blueColor() }, completion: {(finished: Bool) -> Void in println("2:\(formatter.stringFromDate(NSDate()))") }) }, completion: {(finished: Bool) -> Void in println("3:\(formatter.stringFromDate(NSDate()))") }) |
実行例:
Optionなしの場合、最初に指定した時間でアニメーションを実行しますが、Optionを指定すると、Optionを指定した時間でアニメーションを実行します。
Optionなし:
実行結果のログ:
Optionあり:
実行結果のログ:
7.UIViewAnimationOptions.OverrideInheritedCurve
直前のアニメーションの曲線の値をキャンセルし、指定した曲線の値でアニメーションを実施します。
サンプルソース:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
UIView.animateWithDuration( 1.5, // アニメーションの時間 delay: 0.5, // アニメーションの遅延時間 options: UIViewAnimationOptions.CurveEaseInOut, // アニメーションの変化オプション animations: {() -> Void in // アニメーションする処理 self.moveView.frame.origin.x = self.containerView.frame.height / 3 * 2 self.moveView.frame.origin.y = 0 self.moveView.backgroundColor = UIColor.redColor() var opt: UIViewAnimationOptions = UIViewAnimationOptions.allZeros if (!isAnimation) { opt = UIViewAnimationOptions.CurveEaseOut } else { opt = UIViewAnimationOptions.CurveEaseOut | UIViewAnimationOptions.OverrideInheritedCurve } UIView.animateWithDuration( 3, // アニメーションの時間 delay: 0.5, // アニメーションの遅延時間 options: opt, // アニメーションの変化オプション animations: {() -> Void in // アニメーションする処理 self.moveView.frame.origin.x = self.containerView.frame.width / 2 - self.moveView.frame.width / 2 self.moveView.frame.origin.y = self.containerView.frame.height - self.moveView.frame.height self.moveView.backgroundColor = UIColor.blueColor() }, completion: {(finished: Bool) -> Void in }) }, completion: {(finished: Bool) -> Void in }) |
実行例:
Optionがない場合、垂直に移動するだけですが、Optionを指定することで、移動時に右側に湾曲するような動きになります。
Optionなし:
Optionあり:
8.UIViewAnimationOptions.AllowAnimatedContent
アニメーション中にanimationsで指定したプロパティの影響を受けます。
サンプルソース:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
var opt: UIViewAnimationOptions = UIViewAnimationOptions.allZeros if (!isAnimation) { opt = UIViewAnimationOptions.TransitionCurlDown } else { opt = UIViewAnimationOptions.TransitionCurlDown | UIViewAnimationOptions.AllowAnimatedContent } UIView.transitionWithView( self.moveView, // 対象のビュー duration: 3, // アニメーションの時間 options: opt, // アニメーション変化オプション animations: {() -> Void in // アニメーションする処理 self.moveView.backgroundColor = UIColor.redColor() }, completion: {(finished: Bool) -> Void in // アニメーション終了後の処理 }) |
実行例:
Optionを指定しない場合は、アニメーションが終わった後に対象のViewが赤になりますが、Optionを指定した場合は、黄緑色からゆっくりと赤色に変わるようになります。
Optionなし:
Optionあり:
9.UIViewAnimationOptions.ShowHideTransitionViews
トランジションメソッドで使用します。遷移する際に元のViewを非表示にします。
サンプルソース:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
self.addView.hidden = true var opt: UIViewAnimationOptions = UIViewAnimationOptions.allZeros if (!isAnimation) { opt = UIViewAnimationOptions.TransitionFlipFromTop } else { opt = UIViewAnimationOptions.TransitionFlipFromTop | UIViewAnimationOptions.ShowHideTransitionViews } UIView.transitionFromView( self.moveView, toView: self.addView, duration: 1, options: opt, // アニメーション変化オプション, completion: {(finished: Bool) -> Void in // アニメーション終了後の処理 println(self.moveView.hidden) }) |
実行例:
UIView.transitionFromViewの第一パラメータで指定したfromViewを非表示にします。ソース中のcompletionブロックで、第一パラメータに指定したViewが、このOptionのありなし、真・偽になることを確認しています。
Optionなし:
実行結果のログ:
Optionあり:
実行結果のログ:
10.UIViewAnimationOptions.OverrideInheritedOptions
※調査中
11.UIViewAnimationOptions.CurveEaseInOut
ゆっくり始まり、一定の速度で進み、ゆっくり終わる。
サンプルソース:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
self.moveView.frame.origin.x = 0 var opt: UIViewAnimationOptions = UIViewAnimationOptions.allZeros if (!isAnimation) { opt = UIViewAnimationOptions.CurveLinear } else { opt = UIViewAnimationOptions.CurveEaseInOut } UIView.animateWithDuration( 3, // アニメーションの時間 delay: 0.5, // アニメーションの遅延時間 options: opt, // アニメーションの変化オプション animations: {() -> Void in // アニメーションする処理 self.moveView.frame.origin.x = self.containerView.frame.width - self.moveView.frame.width self.moveView.backgroundColor = UIColor.redColor() }, completion: {(finished: Bool) -> Void in // アニメーション終了後の処理 }) |
実行例:
Optionを有効にした場合は、最初と最後がゆっくりで、途中は一定の速度で進むことが確認出来ます。
12.UIViewAnimationOptions.CurveEaseIn
ゆっくり始まり、後は一定の速度で進む
サンプルソース:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
self.moveView.frame.origin.x = 0 var opt: UIViewAnimationOptions = UIViewAnimationOptions.allZeros if (!isAnimation) { opt = UIViewAnimationOptions.CurveLinear } else { opt = UIViewAnimationOptions.CurveEaseIn } UIView.animateWithDuration( 3, // アニメーションの時間 delay: 0.5, // アニメーションの遅延時間 options: opt, // アニメーションの変化オプション animations: {() -> Void in // アニメーションする処理 self.moveView.frame.origin.x = self.containerView.frame.width - self.moveView.frame.width self.moveView.backgroundColor = UIColor.redColor() }, completion: {(finished: Bool) -> Void in // アニメーション終了後の処理 }) |
実行例:
Optionを有効にした場合は、最初はゆっくりで、後は一定の速度で進むことが確認出来ます。
13.UIViewAnimationOptions.CurveEaseOut
一定の速度で進み、 ゆっくり終わる
サンプルソース:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
self.moveView.frame.origin.x = 0 var opt: UIViewAnimationOptions = UIViewAnimationOptions.allZeros if (!isAnimation) { opt = UIViewAnimationOptions.CurveLinear } else { opt = UIViewAnimationOptions.CurveEaseOut } UIView.animateWithDuration( 3, // アニメーションの時間 delay: 0.5, // アニメーションの遅延時間 options: opt, // アニメーションの変化オプション animations: {() -> Void in // アニメーションする処理 self.moveView.frame.origin.x = self.containerView.frame.width - self.moveView.frame.width self.moveView.backgroundColor = UIColor.redColor() }, completion: {(finished: Bool) -> Void in // アニメーション終了後の処理 }) |
実行例:
Optionを有効にした場合は、一定の速度で進み、最後がゆっくりになる事が確認出来ます。
14.UIViewAnimationOptions.CurveLinear
一定の速度で進む
サンプルソース:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
self.moveView.frame.origin.x = 0 var opt: UIViewAnimationOptions = UIViewAnimationOptions.allZeros if (!isAnimation) { opt = UIViewAnimationOptions.CurveEaseInOut } else { opt = UIViewAnimationOptions.CurveLinear } UIView.animateWithDuration( 3, // アニメーションの時間 delay: 0.5, // アニメーションの遅延時間 options: opt, // アニメーションの変化オプション animations: {() -> Void in // アニメーションする処理 self.moveView.frame.origin.x = self.containerView.frame.width - self.moveView.frame.width self.moveView.backgroundColor = UIColor.redColor() }, completion: {(finished: Bool) -> Void in // アニメーション終了後の処理 }) |
実行例:
Optionを有効にした場合は、最初から最後まで一定の速度で進むことが確認出来ます。
15.UIViewAnimationOptions.TransitionNone
トランジションメソッドで使用します。何もしません。
サンプルソース:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
var opt: UIViewAnimationOptions = UIViewAnimationOptions.allZeros if (!isAnimation) { opt = UIViewAnimationOptions.TransitionFlipFromLeft } else { opt = UIViewAnimationOptions.TransitionNone } UIView.transitionWithView( self.moveView, // 対象のビュー duration: 1, // アニメーションの時間 options: opt, // アニメーション変化オプション animations: {() -> Void in // アニメーションする処理 }, completion: {(finished: Bool) -> Void in // アニメーション終了後の処理 self.moveView.backgroundColor = UIColor.redColor() }) |
実行例:
16.UIViewAnimationOptions.TransitionFlipFromLeft
トランジションメソッドで使用します。左辺が手前に回って右辺になるようなアニメーションです。
サンプルソース:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
var opt: UIViewAnimationOptions = UIViewAnimationOptions.allZeros if (!isAnimation) { opt = UIViewAnimationOptions.TransitionNone } else { opt = UIViewAnimationOptions.TransitionFlipFromLeft } UIView.transitionWithView( self.moveView, // 対象のビュー duration: 1, // アニメーションの時間 options: opt, // アニメーション変化オプション animations: {() -> Void in // アニメーションする処理 }, completion: {(finished: Bool) -> Void in // アニメーション終了後の処理 self.moveView.backgroundColor = UIColor.redColor() }) |
実行例:
Optionを有効にした場合は、左辺が手前に回って右辺になるようなアニメーションを確認出来ます。
17.UIViewAnimationOptions.TransitionFlipFromRight
トランジションメソッドで使用します。左辺が背後に回って右辺になるようなアニメーションです。
サンプルソース:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
var opt: UIViewAnimationOptions = UIViewAnimationOptions.allZeros if (!isAnimation) { opt = UIViewAnimationOptions.TransitionNone } else { opt = UIViewAnimationOptions.TransitionFlipFromRight } UIView.transitionWithView( self.moveView, // 対象のビュー duration: 1, // アニメーションの時間 options: opt, // アニメーション変化オプション animations: {() -> Void in // アニメーションする処理 }, completion: {(finished: Bool) -> Void in // アニメーション終了後の処理 self.moveView.backgroundColor = UIColor.redColor() }) |
実行例:
Optionを有効にした場合は、左辺が背後に回って右辺になるようなアニメーションを確認出来ます。
18.UIViewAnimationOptions.TransitionCurlUp
トランジションメソッドで使用します。ページをめくり上げる様なアニメーションです。
サンプルソース:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
var opt: UIViewAnimationOptions = UIViewAnimationOptions.allZeros if (!isAnimation) { opt = UIViewAnimationOptions.TransitionNone } else { opt = UIViewAnimationOptions.TransitionCurlUp } UIView.transitionWithView( self.moveView, // 対象のビュー duration: 1, // アニメーションの時間 options: opt, // アニメーション変化オプション animations: {() -> Void in // アニメーションする処理 }, completion: {(finished: Bool) -> Void in // アニメーション終了後の処理 self.moveView.backgroundColor = UIColor.redColor() }) |
実行例:
Optionを有効にした場合は、ページをめくり上げる様なアニメーションを確認出来ます。
19.UIViewAnimationOptions.TransitionCurlDown
トランジションメソッドで使用します。TransitionCurlUpの逆のアニメーションです。
サンプルソース:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
var opt: UIViewAnimationOptions = UIViewAnimationOptions.allZeros if (!isAnimation) { opt = UIViewAnimationOptions.TransitionNone } else { opt = UIViewAnimationOptions.TransitionCurlDown } UIView.transitionWithView( self.moveView, // 対象のビュー duration: 1, // アニメーションの時間 options: opt, // アニメーション変化オプション animations: {() -> Void in // アニメーションする処理 }, completion: {(finished: Bool) -> Void in // アニメーション終了後の処理 self.moveView.backgroundColor = UIColor.redColor() }) |
実行例:
20.UIViewAnimationOptions.TransitionCrossDissolve
トランジションメソッドで使用します。クロスディゾルブ、じわっと現れるようなアニメーションです。
サンプルソース:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
var opt: UIViewAnimationOptions = UIViewAnimationOptions.allZeros if (!isAnimation) { opt = UIViewAnimationOptions.TransitionNone } else { opt = UIViewAnimationOptions.TransitionCrossDissolve } UIView.transitionWithView( self.moveView, // 対象のビュー duration: 1, // アニメーションの時間 options: opt, // アニメーション変化オプション animations: {() -> Void in // アニメーションする処理 }, completion: {(finished: Bool) -> Void in // アニメーション終了後の処理 self.moveView.backgroundColor = UIColor.redColor() }) |
実行例:
21.UIViewAnimationOptions.TransitionFlipFromTop
トランジションメソッドで使用します。上底が背後に回って下底になる様なアニメーションです。
サンプルソース:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
var opt: UIViewAnimationOptions = UIViewAnimationOptions.allZeros if (!isAnimation) { opt = UIViewAnimationOptions.TransitionNone } else { opt = UIViewAnimationOptions.TransitionFlipFromTop } UIView.transitionWithView( self.moveView, // 対象のビュー duration: 1, // アニメーションの時間 options: opt, // アニメーション変化オプション animations: {() -> Void in // アニメーションする処理 }, completion: {(finished: Bool) -> Void in // アニメーション終了後の処理 self.moveView.backgroundColor = UIColor.redColor() }) |
実行例:
22.UIViewAnimationOptions.TransitionFlipFromBottom
トランジションメソッドで使用します。上底が手前に回って下底になる様なアニメーションです。
サンプルソース:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
var opt: UIViewAnimationOptions = UIViewAnimationOptions.allZeros if (!isAnimation) { opt = UIViewAnimationOptions.TransitionNone } else { opt = UIViewAnimationOptions.TransitionFlipFromBottom } UIView.transitionWithView( self.moveView, // 対象のビュー duration: 1, // アニメーションの時間 options: opt, // アニメーション変化オプション animations: {() -> Void in // アニメーションする処理 }, completion: {(finished: Bool) -> Void in // アニメーション終了後の処理 self.moveView.backgroundColor = UIColor.redColor() }) |
実行例:
4.スプリング効果
UIView.animateWithDuration(duration, delay, usingSpringWithDamping, initialSpringVelocity, options , animations, completion)メソッドを使用するとスプリング効果を得られます。
スプリング効果のパラメタは次の2つが関係しています。
usingSpringWithDamping:バネの振動する量を設定します。0〜1の間で指定ができ、1の時は振動せず、0に近いほど振動します。
initialSpringVelocity:バネの初速を設定します。0〜1の間で指定ができ、1の時は初速が遅く、0に近いほど初速が早くなります。
それぞの値を変えると動きは以下のようになります。
1. usingSpringWithDampingの値変化による動きの確認。(initialSpringVelocityは、0.5で固定)
値が大きいほど、終点の動きが少ない事が確認できる。
usingSpringWithDamping:0.1
usingSpringWithDamping:0.5
usingSpringWithDamping:1.0
2. initialSpringVelocityの値変化による動きの確認。(usingSpringWithDampingは、0.1で固定)
値が大きいほうがゆっくり動く事が確認できる。
initialSpringVelocity:0.0
initialSpringVelocity:0.5
initialSpringVelocity:1.0
まとめ
最後まで読んで頂き、ありがとうございました。
UIView.animateWithDurationのアニメーションは如何でしたでしょうか?
上手く使えると、UIやUXの効果が高まります。
次回もぜひご覧ください。
今回のソースは、GitHubに置きましたので、参考にして下さい。(ソースは、少しずつ手が入っており、ブログと異なる場合があります)
UIView.animateWithDurationの定義 maple-watanabe/AnimationEffect
options効果 maple-watanabe/AnimationEffectOptions
スプリング効果 maple-watanabe/AnimationEffectSpring
【Swiftに関連する記事】
・SwiftでStoryboardを使った簡単な画面遷移(メモ的なもの)
・UITableView のセルに配置された UIDatePicker の表示・非表示切り替えを行う。〜 Swiftの話 〜
・SwiftでECSlidingViewControllerを使ったドロワーメニューを実装してみた。