はじめに
こんにちは。HealthCare Innovation Group(HIG)1所属の清水です。
本記事は、夏の自由研究ブログ連載2023の5本目です。
SwiftUIにおけるアラートダイアログを自作で実装する場合、どんな方法があるか考えてみました。
Swiftを用いたiOSアプリ開発で、アラートを自作したいと考えたことはありませんか? Webアプリでもモバイルアプリでも、ユーザに問題を報告したり動作による影響を警告したりする上で、アラートは重要です。
SwiftUIでもalert
が標準で用意されています。ただし、フォントサイズやダイアログのサイズが変更できないため、iPadで利用する場合画面に対してかなり小さく扱いづらいです。
SwiftUI標準のalert
をシミュレータ iPad Pro (12.9-inch) で表示した際の図
画面に対してかなり小さい・・・。
そこで、「自由にカスタマイズできるアラートダイアログを自作する場合、どのような実装方法があるか」を自由研究の題材とすることにしました。
今回試してみた3種類のカスタムアラートを、実装方法と共に紹介したいと思います。
※もっと良い実装方法をご存知でしたら、教えていただきたいです!
本記事では触れていませんが、カスタムアラートダイアログに関するライブラリも公開されています。合わせて確認頂けると良いと思います(例: CustomAlert)
検証内容
アラートは、通常の画面より手前(通常画面に重なる形)に表示します。
今回は、重ねて表示するためのコンポーネントの中から、以下の3種類の実装方法で比較していきたいと思います。
fullScreenCover
を利用した方法overlay
を利用した方法ZStack
を利用した方法
事前準備
画面に重ねて表示するためのダイアログをViewとして用意しています。SwiftUI標準のalert
に見た目を寄せたアラートViewを、iPad Pro (12.9-inch) 向けにサイズ調整したViewがこちらです。このViewをいくつかの方法で重ねていきます。
※実装は、記事後半に記載しています。
1. fullScreenCover
を利用した方法
1つ目は、fullScreenCover
を利用した方法です。
引数に渡したフラグがtrueの時、全画面を覆うViewをモーダル表示します。
他の方法と比較
- メリット
- 画面全体にモーダル表示するため、アラート表示中に他の動作ができないように制限しやすい。
- デメリット
fullScreenCover
は表示時に画面下から上まで覆うアニメーションを伴って表示するため、アニメーションのカスタマイズが難しい(調べた限りほぼできない)。
アニメーションを非活性にすることはできる。2
2. overlay
を利用した方法
2つ目は、overlay
を利用した方法です。
名前の通り、親Viewより手前に指定したViewを重ねて表示します。アラートの使用用途を考えるとちょうど良さそうです。
他の方法と比較
- メリット
overlay
自体は重ねて表示するだけなので、アニメーションなどをカスタマイズしやすい。
- デメリット
- あくまでも元となるViewに重ねるため、重ねて表示する範囲は呼び出すViewに依存する。
例えば、VStack
に紐づけるとVStack
の範囲が重ねるViewの表示範囲となり、表示範囲外は操作できてしまう(下のgif参照)
- あくまでも元となるViewに重ねるため、重ねて表示する範囲は呼び出すViewに依存する。
3. ZStack
を利用した方法
3つ目は、ZStack
を利用した方法です。fullScreenCover
やoverlay
はViewのInstance Methodを利用していたのですが、こちらは内包するViewの表示順を制御するものなので、毛色が異なります。
他の方法と比較
- メリット
- アプリ大元のViewに重ねることで、画面全体を覆って表示制御できる。
- デメリット
- ダイアログ表示を制御するフラグやダイアログに表示する内容を
App
階層まで伝える必要があるため、単一のView内で状態管理が完結しない。
- ダイアログ表示を制御するフラグやダイアログに表示する内容を
コード実装例
今回利用したソースコードは、こちらです。
App
struct IsShowAlert: EnvironmentKey { |
ContentView
struct ContentView: View { |
Extensions
extension View { |
CustomAlertView
import SwiftUI |
さいごに
本記事では、自由研究としてアラートダイアログを自作する際の実装方法に関して、3種類を比較してみました。
アラートダイアログは性質上、表示中他の操作ができないことが求められると思います。今回試した中では、3つ目のZStack
を利用した方法がアプリ大元のViewに重ねることでアラートを一番手前に表示する要件を満たしやすいと感じました。
また、今回試して分かったメリット・デメリットを以下の表にまとめました。
試した実装方法 | メリット | デメリット |
---|---|---|
1. fullScreenCover を利用した方法 |
画面全体にモーダル表示するため、アラート表示中に他の動作ができないように制限しやすい。 | fullScreenCover は表示時に画面下から上まで覆うアニメーションを伴って表示するため、アニメーションのカスタマイズが難しい(調べた限りほぼできない)。 |
2. overlay を利用した方法 |
overlay 自体は重ねて表示するだけなので、アニメーションなどをカスタマイズしやすい。 |
あくまでも元となるViewに重ねるため、重ねて表示する範囲は呼び出すViewに依存する。 |
3. ZStack を利用した方法 |
アプリ大元のViewに重ねることで、画面全体を覆って表示制御できる。 | ダイアログ表示を制御するフラグやダイアログに表示する内容をApp 階層まで伝える必要があるため、単一のView内で状態管理が完結しない。 |
何かしらの参考になれば幸いです。
参考リンク
https://developer.apple.com/documentation/SwiftUI/View/alert(_:isPresented:actions:)-1bkka
https://developer.apple.com/documentation/swiftui/view/overlay(alignment:content:)
- 1.医療・ヘルスケア分野での案件や新規ビジネス創出を担う、2020年に誕生した事業部です。設立エピソードは未来報の記事をご覧ください。 ↩
- 2.SwiftUI: fullScreenCover with no animation? ↩