So all of the possible ways have been shared above. But i am just concluding them in a single answer and also adding my suggestion too.
- fullScreenCover, How your app is following the navigation experience you can utilize this way.
- Embedding the Tabview inside Navigationview is another option if your deployment target is iOS 14.0, But if you can use 16.0 you can try
. toolbar
API to hide the tabview
- So changing your rootview on window is also an option you will not have tabview with that view but for that you have to provide a animation to your view when its being replaced on window with your push/pop animation, But the overall experience you may lost with this approach like having back button etc, than you have to be responsible for everything like giving a back button its action etc,.
Here are the more details for all of three approaches.
Option 1st is the best way to preset a modal or sheet and show your notification view over there, But it totally depend upon your navigations style or other requirements in your app.
Using option 2nd which is recommended one, you can go ahead but if you are only on iOS 14.0 with 16.0 you can try the apis provided by apple itself.
Using option 3rd its possible but you have to manage everyting by your own on that view, like giving a back button, nav title and its actions etc,
If you want to see some sample code here is the below for 3rd approach.
import SwiftUI
struct ContentView: View {
@State private var selectedTab = 0
@EnvironmentObject var viewSwitch: ViewSwitch
var body: some View {
if viewSwitch.showRoot == .Tabbed {
TabView(selection: $selectedTab) {
AccountView()
.environmentObject(viewSwitch)
.tabItem {
Label("Account", systemImage: "person")
}
.tag(0)
GeneralView()
.tabItem {
Label("General", systemImage: "gear")
}
.tag(1)
}
}
if viewSwitch.showRoot == .WithoutTabbed {
NotificationsView()
.transition(.move(edge: .trailing))
}
}
}
struct AccountView: View {
@State private var showNotifications = false
@State private var isActive = false
@EnvironmentObject var viewSwitch: ViewSwitch
var body: some View {
NavigationView {
VStack {
Text("Account View")
.font(.largeTitle)
.padding()
Button("Go to Notifications") {
showNotifications = true
withAnimation(Animation.easeInOut(duration: 0.5)) {
viewSwitch.changeRootView(to: .WithoutTabbed)
}
}
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
.padding()
}
}
}
}
struct GeneralView: View {
var body: some View {
VStack {
Text("General View")
.font(.largeTitle)
.padding()
}
}
}
struct NotificationsView: View {
var body: some View {
NavigationView {
VStack {
Text("Notification view")
.font(.largeTitle)
.padding()
}
.navigationBarTitle("Notification", displayMode: .large)
}
}
}
@main
struct TestStackOverFlowApp: App {
let viewSwitch = ViewSwitch()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(viewSwitch)
}
}
}
enum WindowRoot {
case Tabbed
case WithoutTabbed
}
class ViewSwitch: ObservableObject {
public init() {}
@Published public var showRoot: WindowRoot = .Tabbed
public func changeRootView(to root: WindowRoot) {
showRoot = root
}
}
Attaching a working video of it.
I hope it helps
It's working for me on Xcode 14.3.