Repository navigation
Use platform-specific navigation transitions - #262
Conversation
iOS now mimics the UINavigationController push/pop: the new screen slides in over the full width while the screen underneath moves 30% and dims slightly. The back swipe follows the finger, and switching tabs no longer animates, like UITabBarController. Android keeps the existing slide-and-fade. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
On the dim amount: Apple doesn't document it, but UIKit dims the screen underneath during a push/pop with a private view ( |
|
I'm not sure this covers the entire scope of #261, but I think it at least closes the gap, so it would be an improvement |
There was a problem hiding this comment.
🟡 Changes recommended
The predictive-back callback lacks the tab-switch guard, causing back gestures between tab roots to slide and dim despite the intended no-animation policy.
1 open issue
What changed in this PR
Introduces platform-specific navigation transitions for the Compose Multiplatform app, addressing #261 while preserving Android’s existing behavior.
Changes:
- Adds iOS push/pop transitions with parallax, dimming, and gesture-driven progress.
- Marks tab destinations to suppress ordinary iOS tab-switch animations.
- Extracts a shared transition contract and adds a theme-controlled dim color.
| File | Description |
|---|---|
| shared/src/iosMain/kotlin/nl/q42/template/navigation/NavigationTransitions.ios.kt | Implements iOS transitions and tab-switch handling. |
| shared/src/commonMain/kotlin/nl/q42/template/navigation/NavigationTransitions.kt | Defines the shared platform transition contract. |
| shared/src/commonMain/kotlin/nl/q42/template/navigation/NavigationRoot.kt | Connects platform transitions to NavDisplay. |
| shared/src/commonMain/kotlin/nl/q42/template/navigation/NavEntryForKey.kt | Adds tab metadata to navigation entries. |
| shared/src/commonMain/kotlin/nl/q42/template/navigation/BottomBarTab.kt | Provides tab metadata and scene detection. |
| shared/src/androidMain/kotlin/nl/q42/template/navigation/NavigationTransitions.android.kt | Preserves Android slide-and-fade transitions. |
| core/ui/src/commonMain/kotlin/nl/q42/template/core/ui/theme/AppColorSchemeLight.kt | Defines the light-theme transition dim color. |
| core/ui/src/commonMain/kotlin/nl/q42/template/core/ui/theme/AppColorSchemeDark.kt | Defines the dark-theme transition dim color. |
| core/ui/src/commonMain/kotlin/nl/q42/template/core/ui/theme/AppColorScheme.kt | Adds the navigation dim color to the theme contract. |
Review effort: Balanced
The dim amount looked good to me. Did you find any documentation from Apple on the other animation specs (speed and motion curve / easing)? Apple Music's exit animation feels a little bit snappier to me when compared 🤔 |
AnneKlapwijk
left a comment
There was a problem hiding this comment.
Looks good, but maybe fix this weird transition behaviour (also see comment: https://github.com/Q42/GoingsOn.CMP/pull/47#pullrequestreview-5751142214):
ScreenRecording_11-03-2026.12-09-43_1.MP4
Ported from GoingsOn.CMP#47: the predictive back transition now also returns noTransition() when going back between two tabs, like the regular pop. After releasing a back swipe, navigation3 finishes in the remaining part of the predictive duration; 250 ms matches UIKit instead of 500 ms. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Ported from GoingsOn.CMP (1e5a6ef1): a back swipe that starts during a push made NavDisplay seek a new transition while the push was still running, so screens ended up in the wrong place and jumped to the end. A decorator now disables back while the entry's transition is running. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Ported from GoingsOn: fade only the top screen over the opaque screen underneath. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

Relates to #261
iOS now mimics the UINavigationController push/pop: the new screen slides in over the full width while the screen underneath moves 30% and dims slightly. The back swipe follows the finger, and switching tabs no longer animates, like UITabBarController. Android keeps the existing slide-and-fade.
Why is this important?
Screen transitions didn't feel native: both platforms used the same custom slide-and-fade. iOS users expect the UINavigationController push/pop, and no slide when switching tabs.
UITabBarController.navigationTransitionDim.Notes
🤖 Generated with Claude Code