I’m trying to abstract an Alert which is being used in multiple places across my app.
I copied and pasted the implementation of func alert(isPresented: Binding<Bool>, content: () -> Alert) -> some View
and tweaked it to adapt it to my usage:
extension View {
func externalURLAlert(isPresented: Binding<Bool>, action: ()) -> some View {
isPresented.wrappedValue ? AnyView(Alert(
title: Text("alert.externalURL.title".localized),
message: Text("alert.externalURL.message".localized),
primaryButton: .cancel(),
secondaryButton: .default(Text("alert.externalURL.openAction.title".localized)) {
action
}
)) : AnyView(EmptyView())
}
}
My plan is to call it on a View like .externalURLAlert(isPresented: $isPresented, action: someAction)
but I’m failing to get the function to compile.
The error I’m getting is the following one:
Initializer ‘init(_:)’ requires that ‘Alert’ conform to ‘View’
3
Answers
try the following:
Plus as written in the error you need to make Alert conform to View.
Also try to use .sheet() — this looks like you search for.
Usage sample: https://www.hackingwithswift.com/quick-start/swiftui/how-to-present-a-new-view-using-sheets
or any that you find by google -> "swiftUI usage .sheet"
The way modifiers work is by returning a modified version of the view they are called on. If you call
Text("").foregroundColor(...)
, you receive a newText
view with a new foreground color. It’s the same with an alert, if you callText("").alert(...
, you receive aText
view that can display an alert on top.Your modifier, on the other hand, completely erases that hierarchy and replaces it with either an empty view, or an alert, but this alert has no information on where it should be presented on.
If what you want is to display a standardized alert, you should leverage the existing modifier with your own parameter, like this:
Notice the use of
self
, because we want to maintain the hierarchy, and.alert(...)
because we’re using the existing system modifier that already knows how to display an alert.You can customize to your own design.
Demo.swift
CustomAlert.swift
CustomAlertButton.swift
CustomAlertModifier.swift
ViewExtension.swift