これは、再生位置の時間がその内容に関係なく画面の中央に表示されるようにするためです。また新たなスライダーは、ユーザーが操作した時のターゲットのメソッドとして同じビューコントローラー内に定義するtSliderMovedを指定しています。さらに、このスライダーのティントカラーをイエローに設定しています。これによって、スライダーの溝の部分の色が黄色になってほかのスライダーと容易に区別できます。
viewDidLoadメソッドの最後では、プレーヤーのデリゲートして、このビューコントローラー自身を指定しています。それにより、プレーヤーの状態変化(「再生が終了した」など)によって、このビューコントローラー内の所定のメソッドが呼び出されるようになります。
新たに追加したラベルとスライダーのレイアウトも、viewWillLayoutSubviewsメソッドの中で設定しています。
すでに述べたように、ラベルは前回のレートスライダーの下で左右方向の中央に置きます。スライダーはさらにその下で、ほぼ場面の幅いっぱいにまたがる感じです。
これは再生機能そのものには関係ありませんが、再生ボタンのタップ処理の中で、今回追加したtSliderのツマミの色(thumbTintColor)を変更しています。再生中はオレンジ、停止中は白になります。
ユーザーがスライダーを動かした際に呼び出されるtSliderMovedメソッドと、再生が終了した際にデリゲートとして呼び出されるaudioPlayerDidFinishPlayingメソッドについては、プログラムを起動して再生中の画面で確認しましょう。
スライダーの操作では、スライダーの位置をプレーヤーの再生時間に変換して再生位置を変更しています。また、再生時間のラベルの「分:秒」表示も更新しています。一方で再生終了時の処理としては、ボタンのタイトルを「Play」に設定してスライダーのツマミを左端に戻し、再生時間の表示も「0:00」に設定しています。
画面ショットだけを見るとそれなりに動いているように見えますが、このままでは再生中でもスライダーはユーザーが動かした位置に止まったままで不自然なユーザーインターフェースとなってしまいます。次にそれを改善していきましょう。
Core Animationの機能を使ってスライダーを自動的に動かす
再生の進行に合わせてスライダーを自動的に動かすには、ちょっと意外かもしれませんが、Core Animationの機能を使います。と言っても、スライダーの動き自体をアニメーション化するのではなく、一定の時間ごとにメソッドを呼び出してもらうためにCore Animationの中のユーティリティー的なクラスであるCADisplayLinkのオブジェクトを使うのです。
同じ目的のためには、ほかにさまざまな方法が考えられますが、これは中でもかなり簡単で手軽に使える方法です。アニメーション以外の用途にも適しています。このプログラムのようにUIKitやAVFoundationをインポートしてあれば、特に新たなフレームワークのインポートは必要ありません。
CADisplayLinkのオブジェクトはtimerとして、ビューコントローラーのプロパティにしました。ただし、ターゲットを設定する関係で初期化はviewDidLoadの中で実行する必要があります。ここでは、一定時間ごとに同じビューコントローラー内のupdateSliderメソッドを呼び出すようにしています。
ユーザーが再生ボタンをタップした際の処理の中では、このタイマーを動かしたり、止めたりします。再生を停止する際には、タイマーのremoveメソッドでタイマーを現在のランループから外し、逆に再生を開始する際には現在のランループにタイマーを追加しています。
これにより、再生中は一定間隔で上で設定したupdateSliderメソッドが呼ばれることになります。その時間間隔は、タイマーのpreferredFramesPerSecondに1を設定しているので1秒に1回となります。
再生ボタンで再生を停止させたときだけでなく、最後まで再生したことで再生が止まった場合にも、タイマーをランループから外す処理を加えています。
タイマーによって一定間隔で呼ばれるupdateSliderメソッドの中では、プレーヤーの再生時間をスライダーのツマミの位置に変換して、スライダーにセットし、さらにスライダーの上の時間表示も更新しています。この際にはDateComponentsFormatterという日時の数字をフォーマットするためのクラスを使っています。オプションは、分と秒だけが「0:00」から始まって「2:34」といったように、最小限の表示となる設定です。
画面のショットだけを見ると前のものと変わり映えしませんが、今度は再生中にスライダーが自動的に動く、自然なユーザーインターフェースになりました。もちろんスライダーのツマミをドラッグして、再生位置を強制的に変更することもできます。
次回の予定
今回はラベルとスライダーを1つずつ追加しただけですが、前回のものと比べると、かなりオーディオプレーヤーらしいプログラムになったのではないかと思います。本当は、再生音のレベルを表示するメーターも付け加えたかったのですが、それは次回に実現することにします。次回はそれだけでなく、再生時間の任意の2点の間でリピートする、いわゆるABリピート機能も実現するつもりです。それによりプログラムの実用性はさらに高くなるでしょう。