Skip to content

Instantly share code, notes, and snippets.

@jason19970210
Last active January 26, 2024 03:31
Show Gist options
  • Save jason19970210/50403b5652c85157112114621acc3752 to your computer and use it in GitHub Desktop.
Save jason19970210/50403b5652c85157112114621acc3752 to your computer and use it in GitHub Desktop.
NavigationStack with iOS 16  - Back to Root View
import SwiftUI
struct ContentView : View {
@EnvironmentObject var router: Router
var body: some View {
NavigationStack(path: $router.path) {
VStack {
// other elements ...
Text("Home")
.padding()
Button("go to FormView"){
router.gotoFormView()
}
}
.navigationDestination(for: Views.self){ destination in
ViewFactory.viewForDestination(destination)
}
}
}
}
import SwiftUI
struct FormView: View {
@EnvironmentObject var router: Router
var body: some View {
NavigationStack(path: $router.path) {
VStack {
// other elements ...
Text("Form")
.padding()
Button("go to PreviewView"){
router.gotoPreviewView()
}
}
.navigationDestination(for: Views.self){ destination in
ViewFactory.viewForDestination(destination)
}
}
}
}
import SwiftUI
enum Views: Hashable {
case HomeView
case FormView
case PreviewView
}
class Router: ObservableObject {
@Published var path = NavigationPath()
func clear() {
path = .init()
}
func gotoFormView() {
path.append(Views.FormView)
}
func gotoPreviewView() {
path.append(Views.PreviewView)
}
}
// class ViewFactory {
//
// static func viewForDestination(_ destination: Views) -> AnyView {
//
// switch destination {
//
// case .HomeView:
// return AnyView(EmptyView()) // since we dont need to make destination directly to HomeView
//
// case .FormView:
// return AnyView(FormView())
//
// case .PreviewView:
// return AnyView(PreviewView())
// }
// }
// }
// Update: 2023.03.16
// just for namespace, modify the type from `class` to `enum` without `return AnyView()`
enum ViewFactory {
@ViewBuilder
static func viewForDestination(_ destination: Views) -> some View {
switch destination {
case .HomeView:
EmptyView() // since we dont need to make destination directly to HomeView
case .FormView:
FormView()
case .PreviewView:
PreviewView()
}
}
}
import SwiftUI
struct PreviewView: View {
@EnvironmentObject var router: Router
var body: some View {
NavigationStack(path: $router.path) {
VStack {
// other elements ...
Text("Preview")
.padding()
Button("back to HomeView"){
router.clear()
}
}
.navigationDestination(for: Views.self){ destination in
ViewFactory.viewForDestination(destination)
}
}
}
}
import SwiftUI
@main
struct ProjectApp: App {
@ObservedObject var router = Router()
var body: some Scene {
WindowGroup {
NavigationStack(path: $router.path){
ContentView()
.navigationDestination(for: Views.self){ destination in
ViewFactory.viewForDestination(destination)
}
}
.environmentObject(router)
}
}
}
@jason19970210
Copy link
Author

jason19970210 commented Jan 26, 2024

If we want to inject some data to the corresponding view, how can we achieve that? Suppose I have a variable in PreviewView and I have to initialise it in the init of PreviewView, how can we do that?

Hello nischalhariqburst,

Thanks for your reply.
Could you give me more information about what kind of data you wish to init for the PreviewView ?

As the time I wrote the article and implemented, I made a Config.swift file for maintain config class and other stuffs with another @EnvironmentObject.

//  PreviewView.swift

struct PreviewView: View {
    
    @EnvironmentObject var router: Router
    @EnvironmentObject var config: Config

    /* .... */
}

And I also put some variable with private var attributes, ex:

    /* ... */
    @EnvironmentObject var config: Config

    private var isChinese: Bool {
        return (config.language == Language.zh_TW) ? true : false
    }
    
    private var preview_string: String {
        return isChinese ? "預覽" : "Preview"
    }
    private var confirm_string: String {
        return isChinese ? "確認" : "Confirm"
    }
    
    private var data: UserData {
        return config.response!.userData
    }

    var body: some View {

        /* ... */

    }

And here is some references FYI:

Please feel free to contact me if you have further questions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment