Push, pop view controller equivalent in SwiftUI
Root :
window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(Model()))
iOS version 13.1 :
class Model: ObservableObject {
@Published var pushed = false
}
struct ContentView: View {
@EnvironmentObject var model: Model
var body: some View {
NavigationView {
VStack {
Button("Push") {
self.model.pushed = true
}
NavigationLink(destination: DetailView(), isActive: $model.pushed) { EmptyView() }
}
}
}
}
struct DetailView: View {
@EnvironmentObject var model: Model
var body: some View {
Button("Bring me Back") {
self.model.pushed = false
}
}
}
Removing the default back button and adding our own will let us get through, until the bug gets fixed by Apple.
class Model: ObservableObject {
@Published var pushed = false
}
struct ContentView: View {
@EnvironmentObject var model: Model
var body: some View {
NavigationView {
VStack {
Button("Push") {
self.model.pushed = true
}
NavigationLink(destination: DetailView(), isActive: $model.pushed) { EmptyView() }
}
}
}
}
struct DetailView: View {
@EnvironmentObject var model: Model
var body: some View {
Button("Bring me Back") {
self.model.pushed = false
}
.navigationBarBackButtonHidden(true)
.navigationBarItems(leading: MyBackButton(label: "Back!") {
self.model.pushed = false
})
}
}
struct MyBackButton: View {
let label: String
let closure: () -> ()
var body: some View {
Button(action: { self.closure() }) {
HStack {
Image(systemName: "chevron.left")
Text(label)
}
}
}
}
more to refer
Is there a .onReappear equivalent in SwiftUI
Attach it instead to splash view directly, so once you come into condition of splash view it will run as expected.
if(showSplash){
Text("Splash screen")
.onAppear(){ ... } // << move here !!
}
iOS SwiftUI: pop or dismiss view programmatically
This example uses the new environment var documented in the Beta 5 Release Notes, which was using a value property. It was changed in a later beta to use a wrappedValue property. This example is now current for the GM version. This exact same concept works to dismiss Modal views presented with the .sheet modifier.
import SwiftUI
struct DetailView: View {
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
var body: some View {
Button(
"Here is Detail View. Tap to go back.",
action: { self.presentationMode.wrappedValue.dismiss() }
)
}
}
struct RootView: View {
var body: some View {
VStack {
NavigationLink(destination: DetailView())
{ Text("I am Root. Tap for Detail View.") }
}
}
}
struct ContentView: View {
var body: some View {
NavigationView {
RootView()
}
}
}
What is equivalent to 'window.rootViewController' in WindowGroup - SwiftUI
With the help of comments and some tutorials, I reached out to the solution (Tested on iOS 15, Xcode 13.2.1):
Add the following code to the Main App Launcher.
struct MyApp: App {
@StateObject var appState = AppState.shared
var body: some Scene {
WindowGroup {
SplashScreenView().id(appState.environment)
}
}
}
And then I created the AppState class, which is the class that when changes I will change the window.
class AppState: ObservableObject {
static let shared = AppState()
@Published var environment = "Production"
}
And whenever I wanted to change the environment and do the same functionality of changing window in UIKit
, do the following :
AppState.shared.environment = "Pre-Production"
How can I pop to the Root view using SwiftUI?
Setting the view modifier isDetailLink
to false
on a NavigationLink
is the key to getting pop-to-root to work. isDetailLink
is true
by default and is adaptive to the containing View. On iPad landscape for example, a Split view is separated and isDetailLink
ensures the destination view will be shown on the right-hand side. Setting isDetailLink
to false
consequently means that the destination view will always be pushed onto the navigation stack; thus can always be popped off.
Along with setting isDetailLink
to false
on NavigationLink
, pass the isActive
binding to each subsequent destination view. At last when you want to pop to the root view, set the value to false
and it will automatically pop everything off:
import SwiftUI
struct ContentView: View {
@State var isActive : Bool = false
var body: some View {
NavigationView {
NavigationLink(
destination: ContentView2(rootIsActive: self.$isActive),
isActive: self.$isActive
) {
Text("Hello, World!")
}
.isDetailLink(false)
.navigationBarTitle("Root")
}
}
}
struct ContentView2: View {
@Binding var rootIsActive : Bool
var body: some View {
NavigationLink(destination: ContentView3(shouldPopToRootView: self.$rootIsActive)) {
Text("Hello, World #2!")
}
.isDetailLink(false)
.navigationBarTitle("Two")
}
}
struct ContentView3: View {
@Binding var shouldPopToRootView : Bool
var body: some View {
VStack {
Text("Hello, World #3!")
Button (action: { self.shouldPopToRootView = false } ){
Text("Pop to root")
}
}.navigationBarTitle("Three")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Related Topics
How to Do "Deep Copy" in Swift
Linker Command Failed with Exit Code 1 After Installing Cocoapods and Firebase Pod
Conditional Property in Swiftui
Cannot Resolve Swift Packages After 15Th March 2022 in Xcode
How to Move to Next Textfield in Swiftui
Swift: How to Read Standard Output in a Child Process Without Waiting for Process to Finish
Firebase Converting Snapshot Value to Objects
How to Create a PDF in Swift with Cocoa (Mac)
Add @Published Behaviour for Computed Property
Deep Copy for Array of Objects in Swift
Swift 3: Set Finder Label Color
How to Add Material to Modelentity Programatically in Realitykit
Firebase Instanceid.Instanceid().Token() Method Is Deprecated
How to Have Two Alerts on One View in Swiftui
Self' Used Before All Stored Properties Are Initialized
How to Make #Selector Refer to a Closure in Swift
Swift 3 Error:Argument Labels '(_:)' Do Not Match Any Available Overloads