【Swift UI】カスタムアラートダイアログの実装方法!ViewBuilder

この記事からわかること

  • Swift UIカスタムアラートダイアログ実装するには?
  • ViewBuilder使い方

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

環境

Swift UIでカスタムダイアログの実装方法

Swift UIを使用してデフォルトで出せる以下のようなデザインのアラートではなく、自分でデザインを変更できるアラートダイアログを実装する方法をまとめていきます。

【SwiftUI】Alertの使い方!複数表示できない理由と解決法 【Swift UI】カスタムアラートダイアログの実装方法!ViewBuilder

実装方法は@ViewBuilderを使用してCustomDialogビューを構築し、ZStackで対象の画面に重ねるだけです。


struct CustomDialog<Content: View>: View {
    
    var content: Content
    @State private var isShow = true
    
    init(@ViewBuilder content: @escaping () -> Content) {
        self.content = content()
    }
    
    var body: some View {
        if isShow {
            ZStack {
                // 画面全体を覆う黒い背景
                Color.black
                    .opacity(0.5)
                    .onTapGesture {
                        isShow = false
                    }
                // ダイアログコンテンツ部分
                content
            // 画面一杯にViewを広げる 
            }.ignoresSafeArea()
        }
    }
}

この実装ではカスタムダイアログのデザインを毎回呼び出し側から変更できるように実装しています。


struct ContentView: View {
    var body: some View {
        ZStack {
            Text("Main View")
            
            CustomDialog {
                VStack {
                    Text("カスタムダイアログ")
                        .frame(width: 200)
                        .padding()
                        .background(.black)
                        .foregroundStyle(.white)
                        .fontWeight(.bold)
                    
                    Spacer()
                    
                    Text("TextTextTextTextTextTextTextTextTextTextText")
                    
                    Spacer()
                }.frame(width: 200, height: 150)
                    .background(Color.white)
                    .clipShape(RoundedRectangle(cornerRadius: 8))
            }
        }
    }
}

呼び出す側と変数を共有したい場合

ダイアログを呼び出す側と変数を共有し、呼び出す側に表示/非表示フラグを持たせたい場合は@Bindingを使用すれば実装することが可能です。


struct CustomDialog<Content: View>: View {
    
    var content: Content
    @Binding var isShow: Bool

    init(isShow: Binding<Bool>, @ViewBuilder content: @escaping () -> Content) {
        self._isShow = isShow
        self.content = content()
    }
    
    var body: some View {
        ZStack {
            Color.black
                .opacity(0.5)
                .onTapGesture {
                    isShow = false
                }
            
            content
        }.ignoresSafeArea()
    }
}

呼び出し側はこのような感じになります。


struct ContentView: View {
    
    @State var isShow: Bool = true
    var body: some View {
        ZStack {
            Text("Main View")
            
            if isShow {
                CustomDialog(isShow: $isShow) {
                    VStack {
                        Text("カスタムダイアログ")
                            .frame(width: 200)
                            .padding()
                            .background(.black)
                            .foregroundStyle(.white)
                            .fontWeight(.bold)
                        
                        Spacer()
                        
                        Text("TextTextTextTextTextTextTextTextTextTextText")
                        
                        Spacer()

                    }.frame(width: 200, height: 150)
                        .background(Color.white)
                        .clipShape(RoundedRectangle(cornerRadius: 8))
                }
            }
        }
    }
}

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index