Programmatic Navigation in SwiftUI explained

แชร์
ฝัง
  • เผยแพร่เมื่อ 28 ก.ย. 2024
  • In this video we take a look at how you can leverage SwiftUI's NavigationStack, NavigationPath and navigationDestination to build an app that can leverage programmatic navigation.
    This video is a companion video for www.donnywals....
    Level up your Swift Concurrency skills with my concurrency course: donnyplus.com/...

ความคิดเห็น • 16

  • @MarcosSuarezAyala
    @MarcosSuarezAyala 3 หลายเดือนก่อน +2

    Thanks for the video, I have a question with the implementation of navigation with the NavigationStack.
    How do I control the navigation? In the case that I only want to navigate when I have received an OK response from the API, if the response has given me an error, I do not perform the navigation and show a pop up. How is this implemented with the NavigationStack?

    • @fitzventure
      @fitzventure 3 หลายเดือนก่อน +2

      This is the one use case nobody covers in any tutorials. I know because I just struggled to figure it out. Say you have a view that displays on initial open of the app, it checks if the user is logged in and navigates to a login page if not. How do you handle that? I turns out , you use a single navigation destination modifier on the root nav stack and a case statement inside that destination checks the path (which you can use and enum for). Think of the navigation destination as a controller for navigation. This would make a great video because it's so common but there's nothing out there explaining it. Hope that helps.

    • @MarcosSuarezAyala
      @MarcosSuarezAyala 3 หลายเดือนก่อน

      @@fitzventure Thanks.
      Now I'm using HomeRoute with enums and special func loadData, I don't like this approach but it's the only thing I can think of for now.
      @MainActor
      func loadData(for route: MoviesRouter) async throws {
      switch route {
      case .detail(let movie):
      do {
      try await Task.sleep(nanoseconds: 5_000_000_000)
      throw(NSError(domain: "error", code: 1)) // To test error
      moviesRouter.append(.detail(movie))
      } catch {
      throw(error)
      }
      }
      }
      And call it in button inside the view
      Button("Go to a random Movie") {
      guard !viewModel.list.isEmpty,
      let randomMovie = viewModel.list.randomElement() else {
      return
      }
      showLoader.toggle()
      Task {
      do {
      try await homeRouter.loadData(for: .detail(randomMovie))
      showLoader = false
      } catch {
      showLoader = false
      showError = true
      }
      }
      }
      .buttonStyle(.borderedProminent)

  • @zbighugh9193
    @zbighugh9193 13 วันที่ผ่านมา

    This doesn't show navigating forwards & backwards to any point in the path. For example: Root -> Dest1 -> Dest2 -> Dest3 -> Dest4 then jump to Dest2 then jump to Root then jump to Dest4, etc.

    • @DonnyWalsdev
      @DonnyWalsdev  8 วันที่ผ่านมา

      With a plain navigation path you wouldn't really be able to achieve that. Luckily, you can also use an array as your navigation path. When doing that, you could easily remove the last 'n' entries to pop back to any place.
      Going back and then forward again isn't possible because NavigationStack always presents the last item in your path. So if you want to go back, you have to drop the items that came after the place you wanted to go to.

  • @indomitabletr1834
    @indomitabletr1834 3 หลายเดือนก่อน +1

    how would it be if I was in iOS 14

    • @DonnyWalsdev
      @DonnyWalsdev  2 หลายเดือนก่อน +1

      A lot less convenient!

  • @enriqueduran6548
    @enriqueduran6548 3 หลายเดือนก่อน +1

    EXCELENT

  • @indiekiduk
    @indiekiduk 3 หลายเดือนก่อน

    It’s strange that navigationDestination doesn’t go through the PreferenceKey’s reducer like navigationTitle does which is how it can be overridden without a warning. Maybe was implemented by a different dev at Apple.

  • @immatiaz
    @immatiaz 2 หลายเดือนก่อน

    Ok but how do you make a view to be presented in full screen mode by using the navigation stack and the path thing ?

    • @DonnyWalsdev
      @DonnyWalsdev  หลายเดือนก่อน

      Do you mean as an overlay? Or pushed on the navigation stack except the top bar is hidden?
      Neither relate to the path to be honest since the path just describes which models are in the stack of presented views. Hiding bars should be possible with the `navigationBarHidden` view modifier.
      If you're looking for an overlay, you'd use the fullScreenCover view modifier. This can't be captured in a navigation stack's path because navigation stack is just a list of views presented in a navigation stack; not including any overlays that you have presented on top of your NavigationStack

  • @indp8752
    @indp8752 3 หลายเดือนก่อน

    When you add an Exercise to path, how does it know that it has to show the Exercise view ?

    • @DonnyWalsdev
      @DonnyWalsdev  2 หลายเดือนก่อน +1

      Through the navigationDestination view modifier that I applied to one of the parent views

  • @marksiracusano9931
    @marksiracusano9931 2 หลายเดือนก่อน

    How would you handle the path if you have a tabView with different navigations for each tab?
    I guess every tab would have a a NavigationStack with their own path, right?
    If so, what if you need new paths further down those flows? Like a child coordinator situation? Should you nest NavigationStacks?

    • @PtolemysEye
      @PtolemysEye 2 หลายเดือนก่อน +1

      Each tab view should have it's own navigation stack

    • @DonnyWalsdev
      @DonnyWalsdev  2 หลายเดือนก่อน +1

      You’d have a dedicated path for each tab. Not sure what you mean by needing new paths later on. You shouldn’t nest navigation stacks, flows later on should use the same path that the stack that contains them would use.
      Of course, sheets can have their own navigation stacks if needed; you just shouldn’t nest them