GraniteNavigationView
public var view: some View {
GraniteTabView(.init(height: tabViewHeight,
paddingTabs: .init(top: tabBarTopPadding, leading: 0, bottom: tabBarBottomPadding, trailing: 0),
paddingIcons: .init(top: topPadding, leading: 0, bottom: bottomPadding, trailing: 0),
landscape: Device.isExpandedLayout,
enableHaptic: false) {
Color.background.fitToContainer()
}, currentTab: 0) {
GraniteTab(ignoreEdges: [.top]) {
Feed()
} icon: {
GraniteTabIcon(name: "house")
}
}
.graniteNavigation(backgroundColor: Color.background) { // <---
Image(systemName: "chevron.backward")
.renderingMode(.template)
.font(.title2)
.contentShape(Rectangle())
}
}GraniteNavigationViews can easily be created with a simple View extension: .graniteNavigation(). Which allows for a custom leading navigation bar icon to use, when popping views back to the parent view.
Only needs to be set once per stack you'd like to create. Later we'd see how adding this view extension to a modal and/or sheet will create a targettable stack to route components or views to from anywhere in an application.
What's Happening Here?
struct GraniteNavigationView<Content: View>: View {
@Environment(\.graniteNavigationStyle) var style
@ObservedObject var routes: GraniteNavigation
let content: () -> Content
init(@ViewBuilder content: @escaping () -> Content) {
if GraniteNavigation.mainSet {
_routes = .init(initialValue: .init(isMain: false))
} else {
_routes = .init(initialValue: .main)
}
self.content = content
GraniteLog("Navigation initializing with \(routes.id)", level: .debug)
}
var body: some View {
mainView
.environment(\.graniteRouter, routes.asRouter)
}
var mainView: some View {
ZStack(alignment: .top) {
style.backgroundColor
.ignoresSafeArea()
.frame(maxWidth: .infinity,
maxHeight: .infinity)
content()// <--- your view
.background(style.backgroundColor)
.onDisappear {
GraniteLog("releasing: \(routes.id)", level: .debug)
routes.releaseStack()
}
GraniteRouter()
.environmentObject(routes)
}
.navBarTitle()
.navBarHidden()
}
}An instance of GraniteNavigation — an ObservableObject that manages the stack — is created. A ZStack is created to mimic a NavigationController.
This will manage the observation of views added to the GraniteRouter the ObservedObject is hosting to push and pop views on top of your main View.