本記事では、SwiftUIにおいてのアラートダイアログ実装方法を見ていきます。
アラートダイアログを用いることで、アプリ内でエラーが発生したり、何らかの処理をする確認の必要があったときに、ユーザーに必要な情報を伝えることができます。
本記事のソースコード
[ 本記事はこんな人におすすめ ]
・SwiftUIでアプリ開発をしている
・アラートダイアログを実装したい
・alertの使い方とカスタマイズについて知りたい
構造体「Alert」は非推奨となった
以前まで使用していた構造体「Alert
」によるアラートダイアログの実装方法は非推奨(Deprecated)となりました。
Appleは代替え案として、iOS15+から使用できるインスタンスメソッド「alert」によるアラートダイアログの実装を推奨しています。
本記事では、新しく推奨されているiOS15+のalertメソッドを用いたアラートダイアログ実装方法について見ていきます。
機能の概要
alertのパラメータ
alertメソッドのパラメータは以下のような構成になっています。
// alertメソッドのパラメータ
func alert(
_ title: S,
isPresented: Binding,
presenting data: T?,
@ViewBuilder actions: (T) -> A,
@ViewBuilder message: (T) -> M
) -> some View where S : StringProtocol, A : View, M : View
【各パラメータの内容】
⚪︎title:
アラートのタイトルとして使用されるテキスト文字列。
⚪︎isPresented:
アラートの表示/非表示を管理するBool値へのバインディング。
⚪︎presenting data:
アラート内容の情報源。「presenting」はラベル。
独自のカスタムデータソースを渡すことができる。
受け取ったデータは、自身のクロージャ内に流し込まれる。
⚪︎actions:
アラート内で実行するアクションを管理するクロージャ。
このクロージャにButtonビューを定義することで、アラート内の
アクションボタンを構成できる。
記述がない場合、アラートを閉じる「OK」ボタンが自動配置される。
⚪︎message:
アラート内のメッセージを構成するクロージャ。Textビューを定義する。
特筆する点としては、独自のデータソースを渡すことができる「presenting data:」というパラメータが用意されています。
このパラメータに渡されたデータソースは、alertのクロージャ「actions:」や「message:」内で扱うことができます。
このパラメータの利用については、後述【独自のデータソースを渡す】で詳しく見ていきます。
基本的な使い方
シンプルな実装コード
アラートダイアログを表示するための最もシンプルな実装コード例を、以下に挙げます。
「isPresented:」に紐付けたBoolプロパティをトグルすることで、画面上にアラートが表示されます。
import SwiftUI
/// iOS15+から使用できるインスタンスメソッドalertによるシンプルなアラート実装
struct BasicAlert: View {
@State private var isShowAlert = false
var body: some View {
Button("アラートを表示する") {
isShowAlert.toggle()
}
.alert("Error", isPresented: $isShowAlert) {
// ダイアログ内で行うアクション処理...
} message: {
// アラートのメッセージ...
Text("エラーが発生しました")
}
}
}
alertの「actions:」クロージャに特に記述が無い場合、自身を非表示にする「OK」ボタンが自動で配置されます。
alertのアクションボタンは、個数や外観において一定のカスタマイズが可能です。カスタマイズについては後述の【ボタンの外観変更】にてご紹介します。
alertを定義する場所
alertを定義する場所は、自身の表示を管理するBool値プロパティを持つファイル内であれば、どこに定義しても動作します。
本記事内では、自身をトグルする役割を持つButtonに対してalertモディファイアを定義していますが、特にボタンに定義しなければならないということはありません。
例えば以下のように、複数の入れ子構成になっている状態で、コンテナビューに対してalertを定義した場合でも、問題なく作動します。
✅ Viewの表示に条件分岐を用いている場合の注意点
if文やswitch文などの条件分岐によってビューを出し分けている場合、条件判定によって隠れているalertは作動しません。
例えば以下のコードは、if文を使ってビューを出し分けている例です。
alertモディファイアが付与されているButtonは現在、if文の条件分岐によって隠れています。
この状態でBool値をトグルしても、アラートは表示されません。
例えば以下のように、条件によって切り替わらないビューに対して定義しておけば、問題なく表示されます。
ボタンの外観変更
アラート内のアクションボタンは、「actions:」クロージャの中にButtonを定義することで、個数や外観において一定のカスタマイズが可能です。
アラートに適切なアクションボタンを配置することで、表示されたアラートに対して取れる操作を、ユーザーにわかりやすく表現することができます。
複数ボタンの設置
クロージャにButtonを複数定義すれば、アラート内に複数のアクションボタンを配置できます。
また、ボタンの数が3つ以上の場合、各ボタンは縦に並べられていきます。
ボタンロールの設定
Buttonの「role:」パラメータに値を渡すことで、そのボタンが持っている役割をユーザーにわかりやすく伝えるための外観が提供されます。
この機能を用いて、アラート内のアクションボタンの外観をカスタマイズすることが可能です。
⚪︎cancel
現在の操作をキャンセルする役割を表現する。
⚪︎destructive
データの削除など、元に戻せないような破壊的な役割を表現する。
「cancel」が設定されたボタンは太字の青色、「destructive」が設定されたボタンは赤色のテキストになります。
また、破壊的な役割を持つボタンが配置されていた時、同列に「cancel」の役割を持つボタンが存在しない場合は、「Cancel」ボタンが自動配置されます。
独自のデータソースを渡す
alertのパラメータ「presenting:」には、独自のアラートデータソースを渡すことができます。
以下に、ドキュメントに記載されている実装を元にしたコード例を挙げます。
実装のおおまかな概要は以下のようになっています。
1. アラートの内容を構成するカスタムデータソースをstructで定義
2. 何らかのデータを保存するカスタムセーブボタン「SaveButton」を用意
3. 2のView内にalertを定義し、「presenting:」にデータソースを渡す
【独自のデータソースを用いたalertの実装例】
import SwiftUI
/// アラートに入力するデータを持つカスタムデータソース
struct SaveDetails: Identifiable {
let id = UUID()
let name: String
let error: String
}
/// 何らかのデータを保存するカスタムボタン。
struct SaveButton: View {
@State private var isShowAlert: Bool = false
@State private var details: SaveDetails?
let alertTitle: String = "Save failed."
var body: some View {
Button("データを保存する") { save() }
.alert(
alertTitle,
isPresented: $isShowAlert,
presenting: details // ⬅︎ ソースを渡す
) { details in
Button("\(details.name)を削除", role: .destructive) {
// データ保存取り消し処理...
}
Button("もう一度試す") {
// 再保存の処理...
}
} message: { details in
Text(details.error)
}
}
/// 何らかのデータを保存するメソッドサンプル
func save() {
// データ保存処理
//...
//...
// データ保存失敗時
details = SaveDetails(name: "データ1",
error: "データの保存に失敗しました。")
isShowAlert.toggle()
}
}
save()メソッドによる保存処理が失敗した時、カスタムデータソースSaveDetailsをdetailsプロパティに格納し、アラートをトグルしています。
アラートは受け取ったデータソースを自身の各クロージャ「actions:」「message:」に流し込みます。
このように、独自で作成したデータソースを渡して、アラートの内容構成に利用することができます。
iOS16+の新機能
アラートに入力フォームを追加する
iOS16+からの新機能として、alertがTextFieldとSecureFieldをサポートするようになりました。
これにより、アラート内に入力フォームを設置することができます。
「actions:」クロージャ内にビューを追加します。
全体の実装コードを以下に挙げておきます。
/// iOS16+から使えるアラート + TextField and SecureField
struct AddTextField: View {
@State private var isShowAlert: Bool = false
@State private var address: String = ""
@State private var password: String = ""
var body: some View {
Button("アラートを表示する") { isShowAlert.toggle() }
.alert("LogIn", isPresented: $isShowAlert) {
TextField("メールアドレス", text: $address)
SecureField("パスワード", text: $password)
Button("キャンセル") {...}
Button("OK") {...}
} message: {
// アラートのメッセージ...
Text("必要な情報を入力してください")
}
}
}
まとめ
以上、SwiftUIのalertメソッドを用いたアラートダイアログ実装についてでした!
要点を以下にまとめます。
・アラート内のアクションボタンは一定のカスタマイズが可能
・定義位置はBool値を持つファイル内のどこでもOK(条件文に注意)
・独自のアラートデータソースを渡すことも可能
筆者自身も、「あれ、アラートが作動しないぞ…??」となった時、条件分岐の判定によってalertが隠れていたのが理由だったことが何度かありましたので、定義位置には注意しましょう!
本記事が参考になれば幸いです。
\ SHARE /
アプリ開発が学べる勉強会を開催中!
CodeCandyではアプリ開発を学ぶための勉強会を定期開催しています。
学習する習慣を身につけたい、他の参加者と作業したい、アプリ開発の基本をマスターしたい、という方のために無料で学べる勉強会です。
グループにメンバー登録して頂くと、イベント開催時にメールで通知されます。
徹底した基礎学習からマスターするiPhoneアプリ開発集中オンライン講座開講!
本書「iPhoneアプリ開発集中講座」を執筆している現役エンジニア講師陣が直接に指導!
基礎、課題実習で実践力を鍛えて、オリジナルアプリ公開までチャレンジ!
充実した転職支援もあるので、エンジニアへ転職したい人にもおすすめです!
まずは、現役エンジニアに相談できる無料相談をご利用ください。