How to change the Navigation View Style of a Navigation View depending on a @State in SwiftUI?

Viewed 570

I am currently working with Navigation View in SwiftUI.

Problem: I would like to change the Navigation View Style from an Descendent View using @State & @Binding.

@Binding var defaultNavigationStyle: Bool
    
var body: some View {
    NavigationView {
        sidebar
            
        Text("Choose an Option from the Sidebar.")
            
        Text("Select an Element.")
    }
    .navigationViewStyle(defaultNavigationStyle ? DefaultNavigationViewStyle() : StackNavigationViewStyle())
}

Obviously, this does not work since the Elements have different Types. Error Message: Result Values in '?:' expression have mismatching types 'DefaultNavigationViewStyle' and 'StackNavigationViewStyle'

Question: How can I change the Navigation View Style using @State & @Binding, without creating a completely different NavigationView and loosing all the State?

1 Answers

You can use a conditional modifier:

extension View {
    typealias ContentTransform<Content: View> = (Self) -> Content

    @ViewBuilder
    func conditionalModifier<TrueContent: View, FalseContent: View>(
        _ condition: Bool,
        ifTrue: ContentTransform<TrueContent>,
        ifFalse: ContentTransform<FalseContent>
    ) -> some View {
        if condition {
            ifTrue(self)
        } else {
            ifFalse(self)
        }
    }
}

and apply it to the NavigationView:

NavigationView {
    sidebar
    Text("Choose an Option from the Sidebar.")
    Text("Select an Element.")
}
.conditionalModifier(
    defaultNavigationStyle,
    ifTrue: { $0.navigationViewStyle(DefaultNavigationViewStyle()) },
    ifFalse: { $0.navigationViewStyle(StackNavigationViewStyle()) }
)
Related