canopas / UIPilot

The missing typesafe SwiftUI navigation library

Home Page:https://canopas.github.io/UIPilot

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Navigate to a new destination and pop backstack upto the new destination

msa1422 opened this issue · comments

In one of my android apps, I have set initial screen to SplashScreen. SplashScreen is responsible for a local database transaction and a couple of network transactions. After transactions, user is navigated to HomeScreen and SplashScreen is removed from the backstack. Is such a behaviour is possible with UIPilot?

One more use case is when navigating from SplashScreen to AuthScreen, then AuthScreen to OnBoardingScreen, then OnBoardingScreen to InitialSettingsScreen and finally from InitialSettingsScreen to HomeScreen. In this use case, all the screens in the backstack should be popped when HomeScreen is reached.

In android, there is a convenience method in NavigationController called "builder.popUpTo(route: String)" which does exactly the same thing that I have mentioned.

Reference from Android docs:
https://developer.android.com/reference/kotlin/androidx/navigation/NavOptions#popUpToRoute()

I have achieved the similar behaviour by the following code

pilot.popTo(splashScreenRoute, inclusive: true)
pilot.push(homeScreenRoute)

With that said, the new destination doesn't animate in. It just appears abruptly.

@msa1422 Your suggestion looks nice. For animation, unfortunately, that's a system limitation. The best you can do is delay push call a bit, that will make sure homeScreenRoute screen animates in.

I tried your suggestion like such

pilot.popTo(splashScreenRoute, inclusive: true)
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) {
    pilot.push(homeScreenRoute)
}

But result is still the same as before, HomeScreen appears without any animation. I think it is because the delay doesn't matter if the call sequence is the same.

Push first and pop after delay also doesn't work because splashScreenRoute remains in backstack somehow.

As a workaround, I have added an opacity animation in SplashScreen and in onAppear of HomeScreen to create a crossfade effect.

Can you try 2.x branch once https://github.com/canopas/UIPilot/tree/2.x ?
It uses UINavigationController under the hood (like NavigationView) but looks much more reliable.

Sure. I will try it within 2-3 days.

Hi @msa1422 Have you had a chance to try it yet?

Hi.
I have played a little bit with the new version. Mainly tested the popTo feature.

  1. popTo first and then push. The HomeScreen still appears without any animation. animation: true on popTo has no effect.
// CASE 1
pilot.popTo(splashRoute, inclusive: true)
pilot.push(homeRoute)
  1. push first and then popTo current destination with inclusive: false. HomeScreen animates in, SplashScreen still remains in the BackStack. Goes back to SplashScreen with back gesture on HomeScreen (Home has navigationBarBackButtonHidden set to true). animation: true on popTo has no effect.
// CASE 2
pilot.push(homeRoute)
pilot.popTo(homeRoute, inclusive: false, animated: false)
  1. push first and then popTo splashRoute with inclusive: true. HomeScreen animates in, SplashScreen removed from BackStack. Can't go back to SplashScreen with back gesture on HomeScreen. HomeScreen is rendered properly, but as soon as slide in navigation animation is complete, HomeScreen turns into a blank page (content disappears). animation: true on popTo has no effect.
// CASE 3
pilot.push(homeRoute)
pilot.popTo(splashRoute, inclusive: true, animated: false)

Please let me know, if there is any other way to navigate in such a pattern. I will test it and let you know.

Case 1 is the correct one, you need to pop first and then push the route. Maybe you can try animated: false in pop call?