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

アラートコントローラーの基本的な使い方

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

2018年04月04日 18時00分

アラートにいろいろなアクションを追加する

 UIAlertControllerクラスのアラートには、複数のアクション、つまりボタンを付加することができます。そのために特別な操作は必要ありません。上の例で見たようにUIAlertActionのオブジェクトを作って、それをUIAlertControllerのaddActionメソッドで追加していけばよいのです。

UIAlertControllerクラスで作るアラートには、実用的な範囲内でいくつでもアクションを追加していくことができます。また、そのアクションには、.default、.destructive、.cancelの3種類が用意されていて、用途に応じて使い分けることができます

 ここでは新しい情報として、アクションには3種類のスタイルがあることを示しておきましょう。すでに上で使った.defaultに加え、.destructiveと.cancelがあります。

 .destructiveは「破壊的」といった意味ですが、このタイプのボタンをタップするとアラートが粉々になるということではありません。これは情報を削除するとか、登録を解除するといった、後戻りできない処理を起動するボタンとして使うためのスタイルです。以前のiOSでは、他とは違う文字の色で表示されていましたが、現バージョンでは見た目で区別することは難しくなっています。もはや過去との互換性を確保するためのスタイルと考えた方がいいかもしれません。

 .cancelは、文字どおりキャンセルボタンのためのものですが、ボタンのタイトルは自由に設定できます。ここでは「キャンセル」としています。このタイプのボタンのタイトルは、ほかより少し太い文字で表示されます。

 プログラムを実行してみましょう。上の例では1つだけだったアラートのボタンが3つになっています。

アクションのスタイルを変えても、現在のiOSでは、.defaultと.destructiveの見た目は変わりません。それに対して、.cancelを指定して作ったアクションのボタンはタイトルが太字で表示されます

 そのぶん、アラートの面積が増えて、デフォルトで付いてくる曇りガラス効果がよりはっきりと認識できるでしょう。

アラートのアクションで画像のコンテントモードを変更する

 ここまでに示したアクションの例では、UIAlertActionのオブジェクトを作る際に、handlerのパラメータには、すべてnilを指定していました。これは、そのボタンをタップしても何も起こらない(アラートを閉じるだけ)ことを意味しています。逆に言えば、ユーザーのボタン操作に対してどのような処理を実行すべきかを、このhandlerとして与えればいいわけです。このhandlerとして渡せるのは、Swiftのクロージャ(無名のファンクション)です。その場に、{}に包んで書くこともできますし、クロージャを代入した変数を指定することも可能です。ここでは後者の方法で、ボタン操作に対する処理を記述してみることにします。

 もちろん、その前にボタン操作で何を実行するのかを考えなければなりません。この例では、ビューコントローラーのビューとして表示している表紙画像のコンテントモードを変更してみることにしましょう。このコンテントモードは、大きさや縦横比の異なるビューに別のビューをはめ込む際に、どのように拡大/縮小するのか、アスペクト比は維持するのかどうか、といったことを指示するためのものでした。

 すでに見たように、表紙画像を表示するためのイメージビューは、viewDidLoadメソッドの中でセットアップしていました。このイメージビューのコンテントモードを、後から別のメソッドで変更したいので、まずイメージビューimgViewをviewDidLoadメソッドの外に出し、このビューコントローラーのプロパティとして定義することにします。

アラートのアクションによってイメージビューのコンテントモードを切り替えられるようにするため、まずイメージビューをviewDidLoadメソッドの外に出して、ビューコントローラーのプロパティとし、このクラスの他の部分からもアクセス可能にします

 次に、ジェスチャーが認識されると呼び出されるlongPressDetectedメソッドの中で、アクションに対する処理を実行するクロージャを定義して、それをactionHandlerという定数に代入しておきます。

アラートに追加する各アクションのhandlerパラメータに設定するクロージャを、キャンセルを除く全アクションに共通なものとして記述し、それをactionHandlerに代入しておきます。どのアクションが操作されたのかは、アクションのタイトルで識別しています

 このハンドラーの外部的仕様は、タップされたボタンに対するアクションそのものを受け取って、何も返さない(Void)というものです。その中の処理では、どのボタンがタップされたのかをアクションのタイトルによって判断し、それに応じたコンテントモードを設定しています。

 新たなアラートコントローラーには、「フィル」「アスペクトフィット」「アスペクトフィル」「センター」といった、4種類のコンテントモードに対するアクション(ボタン)を用意しています。それらのhandlerとしては、すべて上で定義したactionHandlerを設定しています。それにより、ユーザーがアラート上の「キャンセル」以外のボタンをタップすれば、その場でコンテントモードが切り替わるようになります。

各アラートを作成する際のhandlerパラメータに、上で定義したクロージャを代入した定数actionHandlerを指定しています。ハンドラーは、このようにしなくても各アクションのパラメータ部分に直接記述することも可能です。この例の場合は、どちらにしてもコード量は大して変わりません

 このプログラムによって表示したアラートを見て見ましょう。

プログラムを起動して画面を長押しすると、イメージビューのコンテントモードを切り替えるためのアクションを追加したアラートが表示されます。コンテントモードはほかにもありますが、ここではモードが切り替えられることを確かめるために、代表的なものを4つだけ選びました

 ここまでは上の例と実質的に何も変わらりません。「キャンセル」を含めて5つのボタンがアラート上に配置されています。これらのボタンを操作すると、その名前に応じたコンテントモードに切り替わり、表紙写真の表示モードが直ちに切り替わります。

コンテントモードを切り替えるためのアラートで「センター」を選ぶと、画像を拡大/縮小せずに、画面の中央に配置するモードになります。余白部分は黒になっていますが、これはビューの背景色が出現したものです

アラートの外観をカスタマイズする

 UIAlertControllerには、特に見た目をカスタマイズする機能は用意されていません。しかし、何らかの要求でアラートの見栄えを変更したいということもあるかもしれません。そのような要求の例として、アラートを不透明にしてその部分では下のビューがまったく見えなくなるようにしたい、というものを考えてみましょう。それは、アラートに含まれるビューの背景色を設定するという方法で実現できます。ただし、その効果を持つビューはかなり奥のほうにあります。言葉で表せば、アラートのビューの複数あるサブビューのうち最初のものが持つサブビューの最初のものの背景色を設定すればいい、ということになります。コードで書けば以下のようになります。これはそのビューの背景色を黄色に設定する場合です。

let alertContentView = alert.view.subviews.first!.subviews.first!
alertContentView.backgroundColor = .yellow

 ただしこれだけだと、角が丸くない長方形の領域の背景色が変化するだけなので、そのビューのレイヤーの角の半径を設定することで元のアラートの形状に合わせることができます。

alertContentView.layer.cornerRadius = 15

 以上の設定によって、アラートが持つ曇りガラス状の視覚効果の後ろに不透明のビューを挟み込むようなかたちになるため、ビューに設定した不透明な色の上に半透明な曇りガラスを重ねたような淡い色になります。

アラートの見栄えをカスタマイズすることも、ある程度は可能です。これはアラートの構成要であるのビューの1つの背景色を黄色に設定した例です。ここでは不透明色を設定しているので、アラートの背景は透けて見えなくなります。この場合、レイヤーの角の丸みを設定しておくことも必要です

 もう1つ別のカスタマイズ方法として、アラートの視覚効果そのものの、ブラー効果のスタイルを設定することもできます。その設定可能な視覚効果にアクセスするためには、ちょっとおまじないのようなコードが必要になります。言葉では説明し難いので、コードを見てください。

UIVisualEffectView.appearance(whenContainedInInstancesOf: [UIAlertController.classForCoder() as!
UIAppearanceContainer.Type]).effect = UIBlurEffect(style: .dark)

 これはアラートの視覚効果を.darkに設定するものです。この結果、アラートは半透明の曇りガラス効果を保ったまま、そのスタイルが.darkに変更されました。

アラートの中に含まれている視覚効果ビューのブラー効果のスタイルを設定することも可能です。ただし、それだけでは文字が読みにくくなってしまうこともあるので、文字の色など、さらなるカスタマイズが必要となるでしょう。そのためには、やや特殊な方法を開拓する必要があります

次回の予定

 今回は、システムレベルで視覚効果ビューを利用したユーザーインターフェースの1つとして、アラートコントローラーを取り上げました。この機能にはそれほど奥行きがあるというわけではないので、次回はまた話題を転じることにしたいと思います。複数の画像を同時に表示する際に都合の良い、iOSならではのインターフェース機能に触れてみる予定です。

mobileASCII.jp TOPページへ