【SwiftUI】

アラート(alert)のボタンを押したときにアラートを表示する方法

非同期処理でアラートを2つ連続で表示する

投稿日 2021/10/21 更新日 2021/10/21


こんにちは。当サイトの管理者「元木皇天」です。

今回はSwiftUIでiOSアプリを作成してたときに僕がハマった件について記事を書いていこうと思います。

SwiftUIでアラート(alert)を表示してそのボタンを押した後に、第2のアラート画面を表示させたかったのですが全然表示されず困っていたので、その解決方法をこちらに書いています。

備忘録的な感じでややわかりにくい箇所とかあるかもじれませんが、参考にしていただけたら幸いです。

環境
OS:MacOS Big Sur
Xcode:バージョン12.3
Swift:バージョン5.3

やりたいこと

アラートを2つ連続で表示する

実装イメージは以下のような感じです。

アラートを2つ連続で表示する方法

アラートを2つ連続で表示する方法についてですが、まずは2つ連続で表示させる実装ソースコードを以下に表示します。

import SwiftUI

struct ContentView: View {

    //アラートの表示切り替え値
    @State  var isShowAlert: Bool = false

    //2つのアラートのどちらを表示するかを制御するパラメータ
    //true => 1つ目のアラート, false => 2つ目のアラート
    @State  var alertParameter: Bool = false

    var body : some View {
        Button(action: {
            //1つ目のアラートを表示するようにパラメータを変更する
            alertParameter = true
            //アラートを表示する
            isShowAlert = true
        }) {
            Text("ボタン")
        }
        .alert(isPresented: $isShowAlert){
            if (alertParameter){
                return Alert(title: Text("削除してよろしいですか?"),
                            primaryButton: .default(Text("キャンセル")),
                            secondaryButton: .destructive(Text("削除"),
                            action: {
                                //非同期で0.01秒後に2つ目のアラートを表示させる
                                DispatchQueue.main.async{
                                    //2つ目のアラートを表示するようにパラメータを変更する
                                    alertParameter = false
                                    //アラートをもう一度表示させるために再度isShowAlertをtrueにする
                                    isShowAlert = true
                                }
                            })
                )
            }else{
                return Alert(title: Text("削除が完了しました"),
                                dismissButton: .default(Text("OK"))
                )
            }
        }
    }
}

ポイントは2つあります。

まず1つは、.alertの中身をif文で分岐させている箇所です。

alert内のif文の分岐

@State var alertParameter でこのif文を分岐させる値を設定しています。

この値で表示させるアラート(Alert)を制御します。 具体的には、1つ目のアラートで表示されるボタンを押したときの処理(:acrion)にif文の判定値を切り替える処理を入れます。

そうすることで、次に.alertが呼ばれた時にはelse条件に入り、別のアラートが表示されるという感じになっています。


もう1つのポイントは、2つ目のアラートを呼び出すときに、非同期(async)で呼び出すということです。

アラートボタンでの非同期処理

同期処理で呼び出すと2つ目のアラートが表示されないので注意が必要です。

ちなみになぜ非同期なのかというのは、alertのライフサイクルがどういう仕様かわからないので理由は理解できていません。。

非同期にするとできるのでそうしているという感じです。。

動作確認

冒頭でも紹介しましたが、改めて動作をみてみたいと思います。

実際に動かすと以下のような感じになります。

まとめ

SwiftUIでアラートを連続で表示させるには
非同期処理でアラートの内容を切り替えて表示する

参考文献・おすすめ文献