What happened?
On iOS (New Architecture / Fabric), Uniwind.setTheme(theme, { preset }) flips the theme correctly but the animated overlay is never visible — it looks like an instant flip, on every preset (Fade, CircleCenter, …). No error is thrown, and UniwindDiagnostics confirms the shadow tree receives the new theme.
Root cause (confirmed)
In NativePlatformTransition+ios.swift → prepareTransition(type:), the overlay is created with:
if let snapshot = window.snapshotView(afterScreenUpdates: false) { … }
When the visible screen is hosted in react-native-screens native UIViewControllers (native-stack / expo-router native tabs), that content is not yet in the window's committed layer tree at snapshot time, so afterScreenUpdates: false returns a blank/transparent snapshot. The overlay is added and animated, but it's empty → no visible transition.
Decisive A/B repro
Same app, single variable: enableScreens(false) (react-native-screens → plain RN views) makes the transition work perfectly; re-enabling native screens makes it invisible again. Nothing else changed.
Proposed fix (1 line)
window.snapshotView(afterScreenUpdates: true)
The snapshot is taken before the appearance flip, so it still captures the previous theme. Cost is one render flush per user-initiated toggle (negligible). Validated on a physical device — the fade now works on every screen with native-stack + NativeTabs.
Environment
- uniwind-pro 1.3.0
- React Native 0.85.3, Expo SDK 56, New Architecture (Fabric)
- iOS, react-native-screens native-stack + expo-router
NativeTabs
Suggested labels: bug, uniwind-pro, priority.
What happened?
On iOS (New Architecture / Fabric),
Uniwind.setTheme(theme, { preset })flips the theme correctly but the animated overlay is never visible — it looks like an instant flip, on every preset (Fade,CircleCenter, …). No error is thrown, andUniwindDiagnosticsconfirms the shadow tree receives the new theme.Root cause (confirmed)
In
NativePlatformTransition+ios.swift→prepareTransition(type:), the overlay is created with:When the visible screen is hosted in react-native-screens native
UIViewControllers (native-stack /expo-routernative tabs), that content is not yet in the window's committed layer tree at snapshot time, soafterScreenUpdates: falsereturns a blank/transparent snapshot. The overlay is added and animated, but it's empty → no visible transition.Decisive A/B repro
Same app, single variable:
enableScreens(false)(react-native-screens → plain RN views) makes the transition work perfectly; re-enabling native screens makes it invisible again. Nothing else changed.Proposed fix (1 line)
The snapshot is taken before the appearance flip, so it still captures the previous theme. Cost is one render flush per user-initiated toggle (negligible). Validated on a physical device — the fade now works on every screen with native-stack + NativeTabs.
Environment
NativeTabsSuggested labels:
bug,uniwind-pro,priority.