I have a custom view based on TheNeil's answer, that has two levels: MainContent
and SubviewContent
, both are View
s.
The user can navigate from a single MainContent
to many SubviewContent
. This means I make the destination view's content dynamically.
The hierarchy looks like this:
struct StackNavigationView<MainContent, SubviewContent>: View where MainContent: View, SubviewContent: View {
subView: () -> SubviewContent
//...
}
struct SomeView: View {
var body: some View {
StackNavigationView(/*init parameters*/) {
//MainView
}
}
private func subView(forIndex index: Int) -> AnyView {
//some stuff...
}
}
SubviewContent
is built from a method passed from the MainContent
and stored as a variable like so:
let subView: () -> SubviewContent
During initialization, I pass an @escaping
method and assign it to the variable subView
.
init(@ViewBuilder subView: @escaping () -> SubviewContent, /*more stuff*/) {
self.subView = subView
//more stuff...
}
That method returns a view based on an index, like so:
private func subView(forIndex index: Int) -> AnyView {
switch index {
case 0: return AnyView(/*some content*/)
case 1: return AnyView(/*some content*/)
//etc...
default: return AnyView(ViewNotFound())
}
}
The problem is that if I pass a view that requires parameters, the parameters must be hardcoded. Otherwise, the parameters are nil
and the app crashes.
Example case with parameter:
case 1: return AnyView( DestinationView(parameter: some_parameter) )
This crashes because some_parameter
is nil
, when the user tries to navigate.
The same issue appears with optional
parameters. When unwrapped, they are nil
.
I have tried removing the @escaping
bit to solve this issue, but then the app crashes instantly because there are no parameters to pass (again, it passes nil
but for a different reason, obviously).
How can I pass a fully constructed View
only after the users select the navigation destination?
UPDATE 1
Upon review and discussion of the question, I believe a better way to clarify the problem would be this:
How is it possible to maintain in-method parameters while passing the method as a variable?