Expectation: This refers to the desired behavior of the app when a user selects any item from the menu. The expectation is that upon selecting an item, the user should be taken to the corresponding page or view related to that menu item.
Bug: The bug occurs when, after selecting a menu item, instead of navigating to the expected view, it pops back to the main view or the view where the user started.
I have created a custom Navigation and NavigationLink that is capable for multiple ios versions:
struct CustomNavigation<Content>: View where Content: View {
@ViewBuilder var content: () -> Content
var body: some View {
if #available(iOS 16, *) {
NavigationStack(root: content)
} else {
NavigationView(content: content)
.navigationViewStyle(StackNavigationViewStyle())
}
}
struct CustomNavigationLink<Content: View, Destination: View>: View {
let content: () -> Content
let isActive: Binding<Bool>
let destination: () -> Destination
init(@ViewBuilder content: @escaping () -> Content, isActive: Binding<Bool>, @ViewBuilder destination: @escaping () -> Destination) {
self.content = content
self.isActive = isActive
self.destination = destination
}
var body: some View {
if #available(iOS 16, *) {
content()
.navigationDestination(isPresented: isActive) { destination() }
} else {
ZStack {
NavigationLink(isActive: isActive) {
destination()
} label: {
EmptyView()
}
content()
}
}
}
In my TabView, I placed my SideMenuView within the ZStack along with the TabViews. The SideMenuView use my CustomNavigationLink to navigate.
ZStack {
TabView(selection: $tabVM.selection) {...}
SideMenuView()
}
Up to this stage, when attempting to utilize the side menu, it fails to navigate at all. However, I came up with a sketchy solution. Within each tab view, I nested another SideMenu within the CustomNavigation. However, this approach results in the bug I mentioned earlier, where the expected view quickly reverts back to the main view. In response, I opted to embed a SideMenu within each view listed in my menu.
HomeView {
CustomNavigation {
SideMenuView()
...
}
}
As for my solution, I've applied a similar strategy to every item in my menu list.
let initDeviceToken: String = UUID().uuidString
Voila!, everything works even though the compiler returns this error:
The
navigationDestinationmodifier only works inside aNavigationStackorNavigationSplitView. There's a misplacednavigationDestination(isPresented:destination:)modifier presentingLGPrivacyView. It will be ignored.
Please help me to understand why this works. Thanks