compose-multiplatform
compose-multiplatform copied to clipboard
[UIKit] API for navigation between Compose screens
Short description: Provide API for native like(or really native) navigation between Compose screens on iOS with native gestures.
Previous title:
[UIKit] Unclear behaviour of nested UIViewControllers lifecycle
I try to implement something like native uikit navigation for compose using UINavigationController and UiKitView. And i faced the moment when i need to be notified when controller is popped.
I cannot override viewDidDissapear of UIViewController cause ComposeWindow is internal, so i tried to use DisposableEffect for that. But when ComposeWindow pops from UINavigationController, DisposableEffect inside composable block does never execute onDispose.
May be it is not a bug, i am not sure. Is there a way to be notified when nested UIViewController is disappeared?
Affected platforms Select one of the platforms below:
- iOS
Versions
- Kotlin version*: 1.8.20
- Compose Multiplatform version*: 1.4.0
Expected behavior
onDispose called when controller is popped (or viewDidDisappear of ComposeWindow called)
To Reproduce
fun MainViewController() = ComposeUIViewController {
val navController = remember {
UINavigationController(ComposeUIViewController {}).apply {
pushViewController(
viewController = ComposeUIViewController {
Box(Modifier.fillMaxSize()) {
Text(
text = "Close me",
modifier = Modifier.align(Alignment.Center)
)
}
DisposableEffect(0) {
println("HELLO THERE")
onDispose {
println("THIS WOULD NEVER HAPPEN")
}
}
},
animated = true
)
}
}
UIKitView(
modifier = Modifier.fillMaxSize(),
factory = {
navController.view
}
)
}
Thanks! Your current goal is to have native iOS navigation with UINavigationController? Do you want to navigate betwee UIKit and Compose screens, or just navigate between different Compose screens?
I think it's completed to use this code:
UIKitView(
modifier = Modifier.fillMaxSize(),
factory = {
navController.view
}
)
This UIKitView looks redundant.
Maybe we can provide a better API for navigation between Compose screens and between UIKit screen and Compose.
I want to navigate between different compose screens in a native way with swipe gestures and so on. It works and looks perfect btw, but i also want to be notified, when controller is popped from the screen.
Ok, thanks! For now we have different goals for better performance and fixing other bugs in Compose, but this issue is important as well. We will provide the needful API in the future.
Just a little example of what can be done for now with UINavigationController. It is awesome, isn't it?
https://user-images.githubusercontent.com/63979218/231277302-1a7972d4-42bc-4dab-9b6a-8d041db811bf.mp4
Cool!
@alexzhirkevich the plan is to release it as PR in Precompose lib?
@matteocrippa
Multiplatform swipe back navigation was already added to precompose (https://github.com/Tlaster/PreCompose/issues/35). Looks almost the same as native. True native have some limitations and bugs now.
I'm currently experimenting with a way to abstract navigation for all Compose targets in my project. Right now navigation on iOS or Desktop looks the same as on Android - screens are changed with crossfade animation. For now there is no back gesture on iOS (like on Android) but I might consider adding one.
Original issue is related to #3201
Just FYI, Decompose supports the predictive back gesture on all platforms. There is one known bug which I will fix soon, though. https://arkivanov.github.io/Decompose/extensions/compose/#predictive-back-gesture
Plus, there are feature requests to make it better customizable, so it could look closer to the native variant.
Any updates on this? As awesome as the community libraries addressing this are, I think Compose Multiplatform needs first party navigation and resource management solutions as those are parts of the app that can't be migrated easily if a library gets abandoned or isn't quick enough to fix critical bugs or update to newer kotlin/compose releases.
@AhmedMourad0 Thanks! Yeah - you are right! We have resources library and want to enhance it. Code samples https://github.com/JetBrains/compose-multiplatform/blob/master/components/resources/demo/shared/src/commonMain/kotlin/org/jetbrains/compose/resources/demo/shared/UseResources.kt
Also we are looking at navigation as well! For now we are investigating different approaches and trying to find the best direction!
Great news. I'm looking forward to first party solutions for navigation and resource management. In the meantime I've updated my navigation library to benefit from custom transitions and finally published it on Maven Central. As for the string resources on mobile, Android XMLs and iOS Strings Catalog, hidden behind common API works fine for me.
For navigation inside compose we have ported jetpack compose navigation - see https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-navigation-routing.html If you need navigate between native screens and compose - use native/platform solution.
Supporting back gesture is tracked here - https://github.com/JetBrains/compose-multiplatform/issues/4419
Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.
Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.
Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.