最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

swift - NavigationLink in swiftui and routing - Stack Overflow

programmeradmin6浏览0评论

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
            }
        }
    }
}
发布评论

评论列表(0)

  1. 暂无评论