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

なぜスライダーの高さは一定なのか

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

2017年06月26日 17時00分

 これは、配置したばかりのスライダーのサイズを変数sSizeに代入するものです。サイズを知るためだけに書いた行で、そのサイズの値を使って何かするというわけではありません。Swift Playgroundsのデバッグ機能を使ってこの変数の値を調べると、高さ34、幅100だとわかります。

 前回使ったボタンの場合には、ボタンオブジェクト自体のサイズ(bounds)を変更することで、画面上でのボタンの大きさを自由に変更できました。スライダーではどうでしょうか。いろいろなiOSアプリを思い出してみると、スライダーの長さ(横幅)は、いろいろなものがあるような気もしますが、太さ(高さ)は、どれも一定のように思えます。

 試しに、前回と同様にviewWillLayoutSubviewsメソッドを記述し、その中で画面サイズ(ビュー)に合わせてスライダーの長さと太さを設定してみましょう。

viewWillLayoutSubviewsメソッドを記述して、その中でスライダーのサイズを指定しています。高さはビューの高さの5分の1に設定しているはずですが、何も変わりません

 この例では、長さは画面の幅の5分の3、太さは画面の高さの5分の1になるように設定しています。サイズを設定した直後にそのサイズを数字で表示させてみると、確かに高さは312、幅は259.2になっています。ところが実際の表示を見てみると、長さは画面幅の5分の3になっているようですが、高さは前の例と何も変わっていません。

 これはどう考えればよいのでしょう。スライダーが収まっているビューのサイズは、指定したとおりに変更されていることは数字で確かめました。スライダーの長さは、それに合わせて長くなったのに太さが変わっていないのは、スライダー見た目の高さは変更できないことを示しています。つまり枠の大きさは変更することができるのに、中身は変更できないのです。枠を広げた部分は単なる余白になってしまいます。

 よく考えてみると、これはスライダーの場合には合理的だとわかります。スライダーの太さを変更するには、丸いツマミの部分も大きくしなければなりません。そうすると左右方向のスライダーの動く範囲は狭くなってしまい、枠を大きくした意味がないどころか、逆効果になりかねません。そこで、スライダーのツマミの大きさ、つまり太さは一定にして、スライダーの可動範囲を決めるレール部分の長さだけを変更可能にしているのです。

 要するには、スライダーのサイズは、高さをデフォルトの32に固定してまま、幅だけを画面サイズに合わせて、あるいはレイアウトに応じて変更して使うべきものなのです。

スライダーを動かして値の変化を確認する

 前回を思い出してみると、ボタンの場合には「ユーザーがボタンをタップした指を画面から離す」というタイミングで発生するイベントに反応するようにプログラムを書きました。スライダーの場合には、ユーザーがツマミを左右に動かす動きそのものを、イベントとして追跡することができます。言い換えれば、スライダーのツマミの位置が示す値が変化したらそれをイベントとして受け取るようにします。

 とりあえず、ビューの上に1つだけ配置したスライダーの値が変化したら、指定したメソッドを呼ぶように設定してみましょう。イベントの種類が、前回のUIControlEvents.touchUpInsideから、UIControlEvents.valueChangedに変わっていることを除くと、ボタン操作に対するイベント処理とまったくと言っていいほど同じです。

sliderMovedメソッドを追加し、それをスライダーの値が変化した際のイベントを処理するアクションのターゲットとして設定しています

 スライダーの値の変化に応じて呼び出されたメソッドの中では、スライダーオブジェクトのvalueプロパティによって、その値を知ることができます。この場合、値が変化したスライダーオブジェクトは、senderという引数として与えられるので、sender.valueで値を得ることができます。

 Swift Playgroundsのデバッグ機能でその値を確認してみると、変化がグラフ表示されて直感的に把握することができます。

sliderMovedメソッドの中では、動いたスライダーの値はsender.valueで確認できます。スライダーを動かすと、これが連続的に変化するので、変数の値を調べると自動的にグラフ表示になります

RGBに対応した3本のスライダーを配置する

 ここまでで、スライダーの変化した値が取得できるようになりました。今度は、それを利用してビューの色を設定するようなプログラムを書いてみることにしましょう。前回も見たように、色はRGBの3つの要素で指定することができます。そこで、RGBそれぞれの色の要素に対応する3本のスライダーを配置し、それらの値を各色の要素として利用すればよさそうです。

 とりあえず3本のスライダーオブジェクトを作成し、それぞれのアクションのターゲットとなるメソッド名を指定してビューに張り付けます。今回は、3本のスライダーすべてについて、1つのsliderMovedメソッドで対応することにします。

3本のスライダーpgSld1、pgSld2、pgSld3を作成して、親のビューを張り付けます。それぞれのtintColorを赤、緑、青に設定しています

 その際、3本のスライダーのtintColorプロパティを、それぞれ赤、緑、青に設定しています。それによってRGBの要素との対応を表すためです。このtintColorは、iOSのコントロール類の基本的な色合いを設定するものですが、実際にどの部分にその色が反映されるかは、コントロールによって異なります。スライダーの場合は、ツマミの左側のレールの部分が指定した色で着色されます。それはあとで確認しましょう。

 3本のスライダーの配置は、やはりviewWillLayoutSubviewsメソッドの中で設定します。ここでは、少し(50ポイント)ずつずらしながら、縦方向に重なるように並べています。

viewWillLayoutSubviewsの中で、3本のスライダーのサイズと位置を決めています。サイズは同じで、位置のy座標だけを50ポイントずつずらして縦に重ねています

 この時点では、アクションのターゲットとなるsliderMovedメソッドの中身は上の例で示したままで、動かされたスライダーの値を取得するだけのものです。このまま動かして値の変化を確認しましょう。

sliderMovedメソッドの中で取得しているスライダーの値を調べてみると、3本のスライダーの動きが1つのグラフの中に表現されています。どれがどのスライダーの動きかは、まだ識別する必要がありません

 3本のスライダーの動きを1つのメソッドで受けているだけに、3本のスライダーを交互に動かすと、その切り替え部分で値が飛んでいるのがわかります。これは想定内の動きです。

 スライダーのtintColorの設定によって、レール部分に指定した色が着いていることも確認できます。

RGBに対応した3本のスライダーを配置する

 あとは、スライダーの位置によって色を決めて表示するだけですが、その色を着ける対象をまだ決めていませんでした。ビュー全体に着けてもよいのですが、それだとスライダー部分の背景にも色が着いてしまい、せっかくスライダーのレール部分に着けた色がわかりにくくなります。

 そこで、3本のスライダーの下に、色を表示するためだけのビューを配置することにしましょう。

スライダーで調整した色を着けて確認するためだけの目的で、1つのビューpgViewを作成して、親のビューに張り付けます

 そのビューの位置は、やはりviewWillLayoutSubviewsメソッドの中で設定します。またsliderMovedメソッドの中では、3本のスライダーの値をそのままRGBの値として色(UIColorオブジェクト)を作成し、それを新たに配置したビューの背景色に設定しています。

sliderMovedメソッドの中身を書き換えて、3本のスライダーの値からRGBの色を作成し、それをpgViewの背景色に設定しています。3本のスライダーの値はsenderのvalueではなく、pgSld1、pgSld2、pgSld3の各valueプロパティの値として取得します

 スライダーの値の範囲は、デフォルトで0.0~1.0となっています。そのため、そのまま各色要素の値として使えるのです。スライダーでは、ツマミを左端に移動した際の最小値(minimumValue)と、右端に移動した際の最大値(maximumValue)を別々に設定することができます。ほかの用途に利用する場合には、必要に応じて都合のいい値に設定するといいでしょう。

 これで、3本のスライダーの動きによってビューの色が変化する、簡易なカラーピッカーができました。各色要素の値を数字でどこかに表示するようにしてもいいでしょう。

それぞれがRGBの各要素に対応した3本のスライダーを左右に動かすと、それに応じて下のビューの色が変化します。RGBの大小で色がどのように変化するのか、予想しながら動かしてみるだけでも面白いでしょう

次回の予定

 iOSのUIKitに含まれるコントロールとして、前回はボタン、今回はスライダーを取り上げました。UIKitには、まだまだ基本的なコントロールがいくつか含まれています。次回は、macOSなどのデスクトップ用のコントロールと機能的には同じでも、見た目がかなり異なっているiOS独自のコントロール類を取り上げる予定です。

■今回作ったプログラム

Swift_42-1
Swift_42-2
Swift_42-3

mobileASCII.jp TOPページへ