0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SwiftUIでalertを表示するのに便利なExtension

Last updated at Posted at 2021-03-05

SwiftUIのAlertが使いにくかったので、Extensionを作りました。

2021/3/16追記
View以外のコードからアラートを呼び出す方法もありました。コードから呼び出す方が汎用的だと思います。
[SwiftUI] コード(ViewModelなど)からAlertを表示する方法

実装

AlertData.swift
struct AlertData {
    let title: String
    let message: String?
    let primaryText: String?
    let primaryAction: (() -> ())?
    let secondaryText: String?
    let secondaryAction: (() -> ())?

    init(title: String, message: String? = nil, primaryText: String? = nil, primaryAction: (() -> ())? = nil, secondaryText: String? = nil, secondaryAction: (() -> ())? = nil) {
        self.title = title
        self.message = message
        self.primaryText = primaryText
        self.primaryAction = primaryAction
        self.secondaryText = secondaryText
        self.secondaryAction = secondaryAction
    }
}
View+.swift
import SwiftUI

extension View {
    /// Alertを表示する
    ///
    /// 使い方
    ///
    /// Button("Show Alert") {
    ///     showingAlert = true
    /// }
    /// .alert(isPresented: $showingAlert,
    ///        data: AlertData(title: "title",
    ///                        message: "message",
    ///                        primaryText: "primary",
    ///                        primaryAction: {
    ///                         print("primary tapped")
    ///                        },
    ///                        secondaryText: "secondary",
    ///                        secondaryAction: {
    ///                         print("secondary tapped")
    ///                        }))
    func alert(isPresented: Binding<Bool>, data: AlertData) -> some View {
        let title = Text(data.title)
        var messageText: Text? = nil
        if let message = data.message {
            messageText = Text(message)
        }

        var primaryButton: Alert.Button? = nil
        if let primaryText = data.primaryText {
            primaryButton = .default(Text(primaryText)) {
                _ = data.primaryAction?()
            }
        }

        var secondaryButton: Alert.Button? = nil
        if let secondaryText = data.secondaryText {
            secondaryButton = .default(Text(secondaryText)) {
                _ = data.secondaryAction?()
            }
        }

        if let primaryButton = primaryButton, let secondaryButton = secondaryButton {
            return AnyView(alert(isPresented: isPresented, title: title, message: messageText, primaryButton: primaryButton, secondaryButton: secondaryButton))
        } else if let primaryButton = primaryButton {
            return AnyView(alert(isPresented: isPresented, title: title, message: messageText, dismissButton: primaryButton))
        } else if let secondaryButton = secondaryButton {
            return AnyView(alert(isPresented: isPresented, title: title, message: messageText, dismissButton: secondaryButton))
        } else {
            return AnyView(alert(isPresented: isPresented, title: title, message: messageText))
        }
    }

    private func alert(isPresented: Binding<Bool>, title: Text, message: Text?) -> some View {
        alert(isPresented: isPresented) {
            Alert(title: title, message: message)
        }
    }

    private func alert(isPresented: Binding<Bool>, title: Text, message: Text?, primaryButton: Alert.Button, secondaryButton: Alert.Button) -> some View {
        alert(isPresented: isPresented) {
            Alert(title: title, message: message, primaryButton: primaryButton, secondaryButton: secondaryButton)
        }
    }

    private func alert(isPresented: Binding<Bool>, title: Text, message: Text?, dismissButton: Alert.Button) -> some View {
        alert(isPresented: isPresented) {
            Alert(title: title, message: message, dismissButton: dismissButton)
        }
    }
}
0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?