Skip to content

Instantly share code, notes, and snippets.

@klein-artur
Created January 10, 2023 23:00
Show Gist options
  • Save klein-artur/a3aab89959decfa3472fc9f7bca7a03d to your computer and use it in GitHub Desktop.
Save klein-artur/a3aab89959decfa3472fc9f7bca7a03d to your computer and use it in GitHub Desktop.
An alert modifier for better alert handling in SwiftUI
struct AlertAction {
let title: String
var role: ButtonRole? = .none
let action: (() -> Void)
}
struct AlertItem {
let title: String
let message: String
let actions: [AlertAction]
}
struct GeneralAlert: ViewModifier {
@Binding var alertItem: AlertItem?
func body(content: Content) -> some View {
content
.alert(
alertItem?.title.localized ?? "",
isPresented: Binding(
get: {
alertItem != nil
}, set: {
if !$0 {
alertItem = nil
}
}),
presenting: alertItem) { item in
ForEach(item.actions, id: \.title) { action in
Button(role: action.role) {
action.action()
} label: {
Text(action.title.localized)
}
}
} message: { item in
Text(item.message.localized)
}
}
}
extension View {
func generalAlert(item: Binding<AlertItem?>) -> some View {
modifier(GeneralAlert(alertItem: item))
}
}
protocol Localizable {
var localized: String { get }
}
extension String: Localizable {
var localized: String {
return NSLocalizedString(self, comment: "")
}
}
/// Usage:
struct SwiftUIView: View {
@State var alertItem: AlertItem?
var body: some View {
VStack {
Button {
alertItem = AlertItem(
title: "some loc key title",
message: "some loc key message",
actions: [
AlertAction(
title: "action title loc",
action: {
print("do something")
})
]
)
} label: {
Text("show alert")
}
}
.generalAlert(item: $alertItem)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment