Created
April 24, 2024 08:33
-
-
Save cdf1982/9dafe67228e359a7752cf985edb8f7b8 to your computer and use it in GitHub Desktop.
Hopefully a more convenient method to present Alerts in SwiftUI at runtime
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// CustomSwiftUIAlert.swift | |
// Field | |
// | |
// Created by Cesare Forelli on 24/04/24. | |
// | |
import SwiftUI | |
/// ## Bindable object to be presented at runtime in a SwiftUI Alert | |
/// | |
/// Whenever a `CustomSwiftUIAlert` @State variable has a value, SwiftUI automatically presents an Alert via the the provided custom view modifier: | |
/// | |
///```swift | |
/// .alert(with customSwiftUIAlert: Binding<CustomSwiftUIAlert?>) | |
/// ``` | |
/// | |
/// The Alert can have up to 2 customisable buttons: a required Default button and an _optional_ Cancel button. | |
/// | |
/// Closures can be _optionally_ passed to perform actions upon Button presses. | |
/// | |
/// ### Parameters: | |
/// - id: Alert binding objects need to conform to Identifiable; a default UUID value is generated automatically | |
/// - title: _Required_ title to be displayed in the Alert | |
/// - message: _Required_ body message to be displayed in the Alert | |
/// - defaultButtonTitle: _Optional_ title for the confirmation button; if not provided, defaults to "OK" | |
/// - defaultButtonAction: _Optional_ closure containing code to be executed when the Default button in pressed | |
/// - hasCancelButton: By default, no Cancel button is displayed; set to `true` to include a default localised Cancel button in the Alert | |
/// - cancelButtonAction: _Optional_ closure containing code to be executed when the Cancel button in pressed | |
/// | |
/// --- | |
/// | |
/// ### Usage: | |
/// 1. In your SwiftUI file, declare a | |
/// | |
/// ```swift | |
/// @State private var customSwiftUIAlert: CustomSwiftUIAlert? | |
/// ``` | |
/// | |
/// 2. Apply the provided ``CustomAlertViewModifier`` modifier to your SwiftUI View: | |
/// | |
/// ```swift | |
/// content | |
/// .alert(with customSwiftUIAlert: Binding<CustomSwiftUIAlert?>) | |
/// ``` | |
/// | |
/// 3. Whenever you need to display an Alert at runtime, set the `customSwiftUIAlert` variable _(1)_ to a new ``CustomSwiftUIAlert`` object: | |
/// | |
/// ```swift | |
/// customSwiftUIAlert = CustomSwiftUIAlert(title: "Uh oh", | |
/// message: "The server went up in flames", | |
/// defaultButtonTitle: "I'm sad", | |
/// defaultButtonAction: { | |
/// print("You need to purchase a new server") | |
/// }, | |
/// hasCancelButton: true, | |
/// cancelButtonAction: nil) | |
/// ``` | |
/// | |
/// **SwiftUI will take care of presenting the Alert when `customSwiftUIAlert` has a value**. | |
/// | |
struct CustomSwiftUIAlert: Identifiable { | |
let id = UUID() | |
var title: String | |
var message : String | |
var defaultButtonTitle = "OK" | |
var defaultButtonAction : (() -> Void)? = {} | |
var hasCancelButton = false | |
var cancelButtonAction : (() -> Void)? = {} | |
} | |
struct CustomAlertViewModifier: ViewModifier { | |
@Binding var customSwiftUIAlert: CustomSwiftUIAlert? | |
func body(content: Content) -> some View { | |
content | |
.alert(item: $customSwiftUIAlert) { customSwiftUIAlert in | |
if customSwiftUIAlert.hasCancelButton { | |
Alert( | |
title: Text(customSwiftUIAlert.title), | |
message: Text(customSwiftUIAlert.message), | |
primaryButton: .default( | |
Text(customSwiftUIAlert.defaultButtonTitle), | |
action: customSwiftUIAlert.defaultButtonAction | |
), | |
secondaryButton: .cancel(customSwiftUIAlert.cancelButtonAction) | |
) | |
} else { | |
Alert( | |
title: Text(customSwiftUIAlert.title), | |
message: Text(customSwiftUIAlert.message), | |
dismissButton: .default( | |
Text(customSwiftUIAlert.defaultButtonTitle), | |
action: customSwiftUIAlert.defaultButtonAction | |
) | |
) | |
} | |
} | |
} | |
} | |
extension View { | |
/// Convenience custom View modifier to present a ``CustomSwiftUIAlert`` Binding at runtime | |
func alert(with customSwiftUIAlert: Binding<CustomSwiftUIAlert?>) -> some View { | |
modifier(CustomAlertViewModifier(customSwiftUIAlert: customSwiftUIAlert)) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment