I'm not sure if this is possible, but I'm trying to use a protocol function to populate the actions parameter of an .alert modifier in SwiftUI, and I can't figure out exactly how to do it correctly.
The code I'm trying goes like this:
protocol ErrorWithActions: Error {
func alertActions<V: View>() -> V
}
struct MyView: View {
@State var isShowingError = false
var theError: ErrorWithActions? = nil
var body: some View {
Text("Blah blah blah")
.alert(
"An Error Occurred",
isPresented: $isShowingError,
presenting: theError,
actions: { $0.alertActions() } // Compile error here
)
}
}
This won't compile because the actions: { $0.alertActions() } line fails with the compiler error Generic parameter 'Content' could not be inferred.
I think I understand that this doesn't work because .alert's ViewBuilder parameters need to know at compile time what the resulting view will be, and the protocol implementation can't supply that (without the protocol having an associatedtype for its view output, but that would require all cases of an enum implementing the protocol to return the same set of actions, which defeats the purpose of the protocol function).
I implemented a workaround that seems to work, where instead of alertActions() returning a view, it returns an array of AlertAction, a struct that can be translated into the buttons used in the alert, but it would be really nice if I could just supply the buttons directly. Is there a way to do that?
Protocolin place of aViewstruct as a it is never an unsubstantiated object. From Swift.org, "A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality. The protocol can then be adopted by a class, structure, or enumeration to provide an actual implementation of those requirements. Any type that satisfies the requirements of a protocol is said to conform to that protocol."