I am trying to recreate the NavBar behavior that a lot of fitness apps like Strava and AllTrails use to make the activity specific page less busy by removing the NavBar for that specific page.
In AllTrails for example, regardless of which view you are in, if you click on "Navigation" it will remove the NavBar and take you to the activity view providing a back button arrow that takes you to whatever Tab view you were in before you pressed that button. It even remembers what spot you were in on the previous page (if that was. page with a list) meaning that it doesn't refresh the View on the back button but rather is somehow saving the state.
You can see, Strava does the same:
I was able to somewhat replicate a little bit of this behavior using Navigation Stacks:
import SwiftUI
import CoreData
import Foundation
enum Tab {
case Home
case Activity
case PastSessions
}
struct ContentView: View {
@Environment(\.managedObjectContext) private var viewContext
@State var selectedTab: Tab = .Home
var body: some View {
NavigationStack {
TabView(selection: $selectedTab) {
HomeView()
.tabItem {
Image(systemName: "house")
Text("Home")
}
.tag(Tab.Home)
NavigationView {
CurrentSessionView()
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button {
selectedTab = Tab.Home
} label: {
HStack {
Image(systemName: "chevron.backward")
Text("Back")
}
}
}
}
.toolbar(.hidden, for: .tabBar)
}
.tabItem {
Image(systemName: "figure.climbing")
Text("Activity")
}
.tag(Tab.Activity)
[...]
}
}
}
}
The issue is that the Back button here always goes back to the main Home page and for some reason the NavBar only hides on the first time you click the Activity page and navigate "Back". Once you navigate back once, every time you reopen the Activity page it will always show the NavBar until you quit the app and reopen it.
I was going to fix the Back button going to the proper previous page using a variable to remember the last tab before the Activity tab, but I can not figure out what is causing this weird NavBar issue.
I've also tried passing the selectedTab
variable to the child view as a Binding object and having it modify it directly, but that did not fix the issue.
Similar, but not quite the same, StackOverflow posts I've references so far:
- how to switch tab programmatically on button click? in swiftui
- SwiftUI hide TabBar in subview
- SwiftUI Hide TabView bar inside NavigationLink views
- Problem when trying to hide tab bar SwiftUI
I'd really appreciate any tips on how to go about this. Thanks!
In the examples you show, there's no stack view navigation at all, but rather just a presented sheet/cover. Which makes a lot of sense if you do not want to mess up you navigation state when dismissing the sheet. The only issue is that TabViews do not support buttons so you can trigger a value to display the sheet (out of the box). You can have a look at Tabbar middle button utility function in SwiftUI to emulate this behaviour. Using the method in the accepted answer for that question: