I have two Views, ViewA
and ViewB
. Both of them are inside of NavigationStack
and they are inside of a TabView
.
TabbarView:
import SwiftUI
struct TabbarView: View {
var body: some View {
TabView() {
NavigationStack {
ViewA()
}
.tabItem {Label("A", systemImage: "a.circle")}
.tag(0)
NavigationStack {
ViewB()
}
.tabItem {Label("B", systemImage: "b.circle")}
.tag(1)
}
}
}
struct TabbarView_Previews: PreviewProvider {
static var previews: some View {
TabbarView()
}
}
Now on the ViewA, I am presenting a View (TheViewToBeLoadedView
) modally (.fullScreenCover
) with a new NavigationStack.
ViewA:
import SwiftUI
struct ViewA: View {
@State private var isShowingCommonMenu = false
@State private var isPresented = false
@State private var sampleValue = 3
var body: some View {
VStack {
Button {
//MARK: Show Network Configure List
self.isShowingCommonMenu.toggle()
} label: {
Text("GO")
}
.fullScreenCover(isPresented: $isShowingCommonMenu) {
NavigationStack {
FullScreenModalView(isShowingCommonMenu: $isShowingCommonMenu) {
TheViewToBeLoadedView(sampleValue: $sampleValue)
}
}
.background(TransparentBackground())
}
}
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
.background(Color.orange)
.padding()
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
HStack {
Button {
print("aaaaaaaa")
} label: {
Text("Button 1")
}
Button {
print("aaaaaaaa")
} label: {
Text("Button 2")
}
}
}
}
}
}
struct ViewA_Previews: PreviewProvider {
static var previews: some View {
ViewA()
}
}
I use FullScreenModalView
and Load the view inside of a view which has transparent background. You can look at the code if you want to:
FullScreenModalView:
import SwiftUI
struct FullScreenModalView<Content: View>: View {
@Binding var isShowingCommonMenu: Bool
let content: () -> Content
var body: some View {
ZStack {
Color.black.opacity(0.4)
.edgesIgnoringSafeArea(.all)
.onTapGesture {
//Dismiss the modal view when the user taps outside of it
dismiss()
}
VStack {
content()
}
.cornerRadius(10)
.overlay(
Button {
dismiss()
} label: {
DismissButton()
}, alignment: .topTrailing)
}
.ignoresSafeArea(.keyboard)
.edgesIgnoringSafeArea(.all)
.background(TransparentBackground())
}
private func dismiss() {
isShowingCommonMenu = false
}
}
struct FullScreenModalView_Previews: PreviewProvider {
static var previews: some View {
FullScreenModalView(isShowingCommonMenu: .constant(true)) {
Text("This is a custom preview view")
}
}
}
struct TransparentBackground: UIViewRepresentable {
func makeUIView(context: Context) -> UIView {
let view = UIView()
DispatchQueue.main.async {
view.superview?.superview?.backgroundColor = .clear
}
return view
}
func updateUIView(_ uiView: UIView, context: Context) {}
}
struct DismissButton: View {
var body: some View {
ZStack {
Circle()
.frame(width: 30, height: 30)
.foregroundColor(.white)
.opacity(0.6)
Image(systemName: "xmark")
.imageScale(.medium)
.frame(width: 44, height: 44)
.foregroundColor(Color(.label))
}
}
}
It works perfectly, now I can navigate to ViewADetails
from this TheViewToBeLoadedView
by navigationDestination(isPresented
.
TheViewToBeLoadedView:
import SwiftUI
struct TheViewToBeLoadedView: View {
@Binding var sampleValue: Int
@State private var isShowingDetails = false
var body: some View {
Button {
isShowingDetails.toggle()
} label: {
Text("Go to the Details")
}
.frame(width: 300, height: 100, alignment: .center)
.background(Color.yellow)
.navigationDestination(isPresented: $isShowingDetails) {
ViewADetails()
}
}
}
struct TheViewToBeLoadedView_Previews: PreviewProvider {
static var previews: some View {
TheViewToBeLoadedView(sampleValue: .constant(2))
}
}
But when I navigate to the DetailsViewA
you can see it goes out of the Tabbar, because of the new NavigationStack
.
Is it possible to get the current NavigationStack
on the ViewA
and use that instead of using a new NavigationStack?
Thanks!