admin 管理员组

文章数量: 1086019

first of all thanks for attention and your help, so...

in my app I have router from where I log and logout user

@main
struct JobMatchApp: App {
  @StateObject private var vm = RouterViewModel()

    var body: some Scene {
        WindowGroup {
          NavigationStack {
            Router()
          }
          .environmentObject(vm)
        }
    }
}

and from my Router I check if user is logged or not

struct Router: View {
  EnvironmentObject var routerVM: RouterViewModel
  
  var body: some View {
    VStack {
      if routerVM.isUserLoggedIn {
        TabbarView()
      } else {
        LoginView()
      }
    }
    .overlay {
      if routerVM.isLoading {
        VStack {
          ProgressView()
            .tint(.mintGreen)
            .scaleEffect(1.5)
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(.deepNavy)
      }
    }
  }
}

like this it works in tabbar and login perfectly, but somewhere I use NavigationLink it not works any more. for example from view where I go with NavigationLink logout function doesn't work any more. but when I press back button user is logged out and I go to LoginView(), but not automatically I need to press back button. as I said it works perfectly where I dont use NavigationLink or new NavigationStack.

NavigationLink {
            ProfileSettings().toolbar(.hidden)
          } label: {
            Image(systemName: "gearshape")
              .renderingMode(.template)
              .resizable()
              .frame(width: 24, height: 24)
              .foregroundStyle(.mintGreen)
          }

any help?

first of all thanks for attention and your help, so...

in my app I have router from where I log and logout user

@main
struct JobMatchApp: App {
  @StateObject private var vm = RouterViewModel()

    var body: some Scene {
        WindowGroup {
          NavigationStack {
            Router()
          }
          .environmentObject(vm)
        }
    }
}

and from my Router I check if user is logged or not

struct Router: View {
  EnvironmentObject var routerVM: RouterViewModel
  
  var body: some View {
    VStack {
      if routerVM.isUserLoggedIn {
        TabbarView()
      } else {
        LoginView()
      }
    }
    .overlay {
      if routerVM.isLoading {
        VStack {
          ProgressView()
            .tint(.mintGreen)
            .scaleEffect(1.5)
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(.deepNavy)
      }
    }
  }
}

like this it works in tabbar and login perfectly, but somewhere I use NavigationLink it not works any more. for example from view where I go with NavigationLink logout function doesn't work any more. but when I press back button user is logged out and I go to LoginView(), but not automatically I need to press back button. as I said it works perfectly where I dont use NavigationLink or new NavigationStack.

NavigationLink {
            ProfileSettings().toolbar(.hidden)
          } label: {
            Image(systemName: "gearshape")
              .renderingMode(.template)
              .resizable()
              .frame(width: 24, height: 24)
              .foregroundStyle(.mintGreen)
          }

any help?

Share Improve this question asked Mar 27 at 12:55 the middlethe middle 1 3
  • Probably a typo, in Router you should be using @EnvironmentObject var routerVM: RouterViewModel. In addition, ...somewhere I use NavigationLink it not works any more, where do you use this, how do you call this, how do you pass the RouterViewModel to this? Show a minimal reproducible code that produces your issue, see: minimal code. – workingdog support Ukraine Commented Mar 27 at 13:05
  • It's not clear, if - and iff then how, you perform navigation. Basically, you can navigate via providing a navigation path (for example as an observed property of your ViewModel). In that case, you wouldn't want to use NavigationLinks. That means, you would rather use your "CustomNavigationLink" which sends the navigation intent as an event to your view model, but would not immediately execute the navigation. Here you get full control. Otherwise I would recommend to use solely NavigationLinks and don't try to control the navigation path with a view model. What is your requirement? – CouchDeveloper Commented Mar 27 at 13:08
  • From a design perspective, it probably makes more sense, to provide a (separate) NavigationStack in each of TabBarView and LoginView (if required). This will simplify the navigationDestination modifier, and makes your app more modular, making the (valid) assumption, that a Login Scene and a TabBar Scene is completely different, not necessarily requiring a NavigationStack at all. – CouchDeveloper Commented Mar 27 at 13:21
Add a comment  | 

1 Answer 1

Reset to default 0
  1. Uses NavigationPath to control navigation programmatically.

  2. Resets navigation when isUserLoggedIn changes, ensuring it pops to the root.

  3. Use NavigationPath to programmatically manage the navigation stack and reset it on logout:

@State private var navigationPath = NavigationPath()

var body: some View {
    NavigationStack(path: $navigationPath) {
        VStack {
            if routerVM.isUserLoggedIn {
                TabbarView()
            } else {
                LoginView()
            }
        }
        .onChange(of: routerVM.isUserLoggedIn) { isLoggedIn in
            if !isLoggedIn {
                navigationPath = NavigationPath() // Reset to root
            }
        }
    }
}

本文标签: swiftNavigationLink in swiftui and routingStack Overflow