Swift Playgroundsで学ぶiOSプログラミング

画像をフェードアウトさせたり移動させたりするプログラム

文●柴田文彦 編集●吉田ヒロ

2017年07月05日 17時00分

ボタンをフェードアウトさせるアニメーション

 まずは、できるだけ単純なものから始めましょう。アニメーション可能なビューの属性として、もっとも単純なのは、ビューそのものの不透明度を表すalphaでしょう。デフォルトでは1.0に設定されていて、完全な不透明になっています。これを0.0にすると、完全な透明になり、見えなくなってしまいます。その間で値を変化させると、それに合わせて不透明度が変化し、下のものが透けて見える度合いも変化するというわけです。ごく単純に言えば、薄く見えたり濃く見えたりするのです。

 このアニメーションの効果を確かめるために、画面の中央に大きめのボタンを配置しましょう。また、ボタンをタップしたときにアニメーションをスタートできるように、ボタンにはアクションを設定し、そのターゲットのメソッド(ここではbuttonTapped)が呼ばれるように設定します。このあたりの手順については、前回までに何度となく取り上げたので、今回は説明を省きます。コードは、主要部分が、以下に示す画面で確認できるようにしています。

 ボタンがタップされると呼ばれるbuttonTappedの中では2つのことを実行しています。1つはUIViewPropertyAnimatorクラスのオブジェクトとして、アニメーションを作成すること。もう1つはそのクラスのstartAnimationメソッドを起動して、アニメーションをスタートすることです。

UIViewPropertyAnimatorクラスを使ったアニメーションでは、まずアニメーションのオブジェクトを作成してから、それを開始します。アニメーションを作成する際には、長さと速さのカーブを指定し、アニメーションで変化させる属性を変化させる文を記述します

 ここで、アニメーションを作成する際には、durationとcurveという2つのパラメータを指定しています。durationは、アニメーションの長さを決める数値で、単位は秒です。これが大きくなるほどゆっくりとしたアニメーションになるわけです。curveは、アニメーションの実行中の速さの変化をUIViewAnimationCurveという値で指定します。指定可能なのは、ゆっくり始まってだんだん早くなるeaseIn、逆にだんだんゆっくりになるeaseOut、ゆっくり始まって普通の速さになってからゆっくり終わるeaseInOut、そしてずっと同じ速さのlinearの4種類です。ここではlinearを指定しています。

 アニメーションの中身は、animations:{}の中に書きます。一度に複数のビュー属性を変化させることもできますが、ここではボタンのアルファ値を0.1に設定するような1行のコードを書いているだけです。これは現在の状態(デフォルトの1.0)から0.1まで、アニメーションによって変化させるという意味です。

 このプログラムを動かし、ボタンにタップすると、ちょうど2秒かけてボタンの色が薄くなり、消える寸前に止まります。

ボタンのalpha属性をデフォルトの1.0から0.1まで、2秒かけて変化させるアニメーションを実行すると、ボタンがだんだん薄くなり、見えなくなる直前に止まります

 もし、アニメーションの中身でアルファ値を0.0に設定すれば、2秒かけてボタンは完全に見えなくなります。

ビューの中心座標を変化させてビューそのものを移動するアニメーション

 ビューのファルファ値を変化させただけでは、アニメーションを動かすという実感がないという意見もあるでしょう。そこで、こんどはビューそのものを移動させることで、実際にアニメーションが動くという感じを演出してみることにします。そのための最も簡単な方法は、ビューのcenter属性を変化させることです。

 これまでは、主にframe属性としてビューの左上角のXY座標や幅、高さを指定することで、ビューの位置と大きさを指定してきました。このとき自動的に決まるのがビューの中央の点の座標を表すcenter属性です。ビューは長方形なので、左上角のXY座標に、それぞれ幅と高さの半分を加えたものです。このcenter属性は値を調べるだけでなく、変更することも可能です。それによってビューの大きさは変えずに、位置だけを簡単に移動できるのです。

 上に示した例のアニメーションの中身を変更して、ボタンのcenter属性を変化させるようにしてみましょう。ここでは、X座標は親のビューの幅の半分に、Y座標は0に設定してみました。この座標は、左右方向は画面の中央のまま、ボタンの中心が画面の上辺に重なる位置を表します。またついでにアニメーションオブジェクトを作成する際のcurveのパラメータをeaseInに変更しています。

ビュー(ボタン)のcenter属性を2秒かけて変化させ、上下方向の位置が画面(親のビュー)の上辺に重なるように移動するアニメーションを実行します。アニメーションのカーブもeaseInに変更しています

 このプログラムを動かしてボタンをタップすると、2秒間のアニメーションによって、ボタンは真上に移動し、ちょうど半分だけ画面からはみ出した位置で止まります。

ビューのcenter属性を変化させてボタンを動かすアニメーションを実行すると、この場合ボタンは中央から画面の上辺に重なった位置まで移動してから止まります

 curveをeaseInにしたことで、動き出しはゆっくりで、だんだん速くなることも確認できるでしょう。このように、curveのパラメータの効果は、ビューの位置が移動するアニメーションでこそ発揮されます。これをアルファ値の変化で実感するのは、ちょっと難しいでしょう。

ダンピング率を指定して弾む効果を演出

 UIViewPropertyAnimatorクラスのオブジェクトを作成する際のパラメータの与え方には、いま見たのとはまったく別の効果を発揮する方法もあります。それはcurveの代わりにdampingRatioを与える方法です。そのまま訳せばダンピング率ですが、ダンピングとは、車のサスペンションなどに付いているダンパーの効き具合のことです。細かく説明すると長くなりますが、このパラメータは、移動したものが弾むように動きながら徐々に目的位置で止まるようなアニメーションを実現するものです。

 論より証拠で、実際に試してみましょう。上の例のcurveの代わりにdampingRatioを数値で指定します。ここに1.0以上の値を指定すると、curveにlinearを指定したのと同じで、弾むような動作は見られません。値が1.0以下で、かつ小さいほど弾みが大きくなり、なかなか減衰しなくなります。ここでは0.3を指定してみました。また動きがよくわかるように、durationは3.0にしています。アニメーションの中身は上の例と同じです。

アニメーションオブジェクトを作成する際に、curveの代わりにdampingRatioを指定すると、バネとダンパーの組み合わせで弾むような動きのアニメーションを実現できます

 このプログラムを動かしてボタンをタップすると、ボタンが上に移動してちょっと行き過ぎてから、また戻ってくることを何度か繰り返しながら所定の位置に収まる様子が観察できるでしょう。

何度も繰り返して試せるように元に戻って終わるアニメーションに

 ここまでに示した例では、プログラムを起動してからボタンにタップしてアニメーションを動かすと、プログラムを再起動しない限り、二度とアニメーションを試せないようになっていました。これは、アニメーションを実行した結果、ビューの属性が変化してしまい、次にアニメーションを開始しようにもビューの属性に変化する余地がなくなってしまうからです。

 UIViewPropertyAnimatorクラスのアニメーションオブジェクトには、アニメーションが終了した時に実行すべき処理を追加できます。この処理の内容は任意なので、ビューの属性を元に戻すためだけに用意された機能というわけではありません。ここではそれを利用してビューのcenter属性を元の画面の中央に戻すことにします。いったん作成したアニメーションオブジェクトに、addCompleteメソッドを使って処理を追加することになります。書き方は、ちょっと見慣れないものかもしれませんが。{}の中のinに続けて、アニメーション終了時の処理を書けばいいのです。

アニメーションオブジェクトには、addCompletionメソッドによって、アニメーションが終了したときの処理を追加することができます。ここではアニメーションで変化した属性を元に戻しています

 この処理を付け加えることで、この例ではアニメーション終了後にビューが画面の中央に戻ります。ただし、その際にはアニメーションは実行されないので急激な動きになってしまいます。

次回の予定

 今回のアニメーション機能は、その書き方も含めて、以前にも見たことがあると感じた人もいるかもしれません。それもそのはず、この連載で以前に取り上げた「Shape」のテンプレートに含まれるアニメーション機能は、今回取り上げたUIViewPropertyAnimatorを利用したものだったからです。もちろん、Shapeのアニメーションは、そのテンプレートを使ったときしか使えませんが、原理は同じなのです。次回は、今回の手法をもう少し追求して、動きにバリエーションを付けられるようにしてみるつもりです。

■今回作ったプログラム

Swift_45-1
Swift_45-2
Swift_45-3
Swift_45-4

mobileASCII.jp TOPページへ

mobile ASCII

Access Rankingアクセスランキング