Tlaster / PreCompose

Compose Multiplatform Navigation && State Management

Home Page:https://tlaster.github.io/PreCompose/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[BUG] `NavTransition::createTransition` and `destroyTransition ` not used when navigating

Dambakk opened this issue · comments

I have defined the following NavTransition:

val slideEnterFromLeftTowardsRight: (width: Int) -> Int = { width -> -width }
val slideExitTowardsLeft: (width: Int) -> Int = { width -> -width }
val slideExitTowardsRight: (width: Int) -> Int = { width -> width }
val slideEnterFromRightTowardsLeft: (width: Int) -> Int = { width -> width }

val defaultNavTransition = NavTransition(
        createTransition = slideInHorizontally(
            initialOffsetX = slideEnterFromRightTowardsLeft,
        ),
        destroyTransition = slideOutHorizontally(
            targetOffsetX = slideExitTowardsRight,
        ),
        pauseTransition = slideOutHorizontally(
            targetOffsetX = slideExitTowardsLeft,
        ),
        resumeTransition = slideInHorizontally(
            initialOffsetX = slideEnterFromLeftTowardsRight,
        ),
    )

and provided it to the NavHost like the following:

    val navController = rememberNavigator()
    NavHost(
        modifier = Modifier.fillMaxSize(),
        navigator = navController,
        initialRoute = "list",
        navTransition = defaultNavTransition,
        swipeProperties = remember { SwipeProperties() }

    ) {
        scene(
            ...
      }

Bug: When navigating from screen A to B none of the transitions are used. When popping the backstack from B to A I get the expected transition as defined above. Same behaviour on both android and ios.

Have I misconfigured anything or is there a bug in PreCompose?

PreCompose version: 1.6.0

Hi, do you have a more complete example for this? since I can not reproduce this issue.

Here is my code up until the nav configuration:

fun App() {
    PreComposeApp {
        AdaptiveTheme(
            material = MaterialThemeSpec.Default(),
            cupertino = CupertinoThemeSpec.Default(),
            content = {
                KoinContext {
                    AppNavigationPrecompose()
                }
            }
        )
    }
}
@Composable
fun AppNavigationPrecompose() {
    val navController = rememberNavigator()
    NavHost(
        modifier = Modifier.fillMaxSize(),
        navigator = navController,
        initialRoute = "list",
        navTransition = defaultNavTransition, // from snippet above
        swipeProperties = remember { SwipeProperties() }
    ) {
        scene("A") {
            A(
                someCallback = {
                    navController.navigate("B")
                },
            )
        }

        scene("B") { 
            B(
                someCallback = {
                    navController.popBackStack()
                },
            )
        }
    }
}

and here is a screen recording of how it works with that code (the list screen is A, and the details screen is B):

recording.mov

Does this help illustrate what my problem is?

Sorry, it is still quite hard to figure out the issue. I tried to use the sample app to reproduce the issue, but without success.
However, I might have some clues about this issue, just not quite sure yet. Currently, the NavHost's animation needs some improvement.
Still, it would be better if you could provide a more complete sample for this issue.

Almost same here.

scene(
            route = NavigationTree.AuthFlow.Login.name,
            navTransition = getNavTransition(
                createDirection = {
                    if (previousEntry?.route?.route == NavigationTree.AuthFlow.Main.name) SlideDirection.Left
                    else SlideDirection.Right
                },
                destroyDirection = {
                    if (previousEntry?.route?.route == NavigationTree.AuthFlow.Main.name) SlideDirection.Left
                    else SlideDirection.Right
                }
            )
        ) {
          SomeComposable()
}
fun getNavTransition(
    createDirection: () -> SlideDirection,
    destroyDirection: () -> SlideDirection,
    pauseDirection: () -> SlideDirection = destroyDirection,
    resumeDirection: () -> SlideDirection = createDirection
): NavTransition {
    return object : NavTransition {
        override val createTransition: EnterTransition
            get() = slideIntoContainer(createDirection())
        override val destroyTransition: ExitTransition
            get() = slideOutOfContainer(destroyDirection())
        override val pauseTransition: ExitTransition
            get() = slideOutOfContainer(pauseDirection())
        override val resumeTransition: EnterTransition
            get() = slideIntoContainer(resumeDirection())
    }
}

When I navigate to this screen using this code:

val toLoginScreen: () -> Unit = remember {
        {
                navigator.navigate(
                    route = NavigationTree.AuthFlow.Login.name
                )
        }
    }

navigation works as expected! scene is recomposing, it's navTransition triggers and checking previous entry and I'm getting correct slide direction.

But if i use NavOptions:

val toLoginScreen: () -> Unit = remember {
        {
                navigator.navigate(
                    route = NavigationTree.AuthFlow.Login.name,
                    options = NavOptions(
                        popUpTo = PopUpTo.First()
                    )
                )
        }
    }

scene is not recomposing, it's navTransition not recalculating and i get wrong direction.

Checking with debug stop points at "if(....)". With NavOptions PopUpTo it's not stopping there

WrongDirection.webm
CorrectDirection.webm