1# Mobile navigation
2
3Home and thread routes share the [root native stack](../../apps/mobile/src/Stack.tsx)
4so UIKit can animate the header within one navigation controller. The iPad sidebar
5has its own stack. Splitting Home and threads between controllers loses that
6continuous transition.
7
8## UIKit constraints
9
10The [react-native-screens patch](../../patches/react-native-screens@4.26.2.patch)
11preserves behavior that is easy to break when changing native headers:
12
13- The brand belongs in `headerTitle`. On iOS 26.5, UIKit morphs a background-free
14 leading toolbar item's rectangle into the next screen's glass back button,
15 even when the items have different identifiers.
16- UIKit's scroll-edge fade does not recognize Fabric text views. An empty native
17 label supplies the custom title's geometry. Removing that apparently unused
18 view changes the fade.
19- Leading, trailing, and center item groups need independent caches. A button can
20 belong to only one group; rebuilding an unchanged group can pull its buttons
21 out of a group UIKit is still animating. Cache ownership also includes the
22 header config, whose event emitter changes on remount.
23- A horizontal ScrollView at its leading edge must yield to the full-screen back
24 gesture. Upstream gives every horizontal ScrollView priority, so swiping back
25 on a code block or table can only bounce its content.
26
27The patch adds native header props that require code generation and a new binary.
28Patch rebuild guidance lives in the
29[mobile development README](../../apps/mobile/README.md#development).
30
31## Native media presentations
32
33iOS delegates full-screen video to [AVKit](../../apps/mobile/modules/t3-native-controls/ios/T3NativeVideoPresentation.swift)
34and images and documents to [Quick Look](../../apps/mobile/modules/t3-native-controls/ios/T3NativeFilePresentation.swift).
35Each framework owns its controls and transition. A separate UIKit zoom transition
36prevents AVKit's native Close action from exiting full screen and interferes with
37Quick Look's interactive return to its thumbnail. The AVKit entry selector is
38guarded, with standard modal presentation as the fallback.
39
40[Thumbnail registration](../../apps/mobile/modules/t3-native-controls/ios/T3NativePresentation.swift)
41holds weak view references for transition and share-sheet anchors. It does not own
42the preview; a source row can disappear while a native presentation is open.
43Identifiers must distinguish attachments that are visible at the same time.
44Native promises complete after dismissal so callers keep local file leases until
45the preview or share flow has finished.
46
47Treat a dismissal request as pending until UIKit finishes its current transition.
48Starting another dismissal while presentation or an interactive dismissal is
49settling can strand the controller. Video cleanup restores the previous audio
50configuration only if it still matches the preview's configuration. It must not
51deactivate the shared audio session, which may belong to another player or recorder.
52
53Video playback holds the first signed asset URL for the lifetime of the preview.
54Following credential refreshes reactively would restart playback. Quick Look copies
55original bytes into its own temporary directory so preview and sharing cannot
56mutate a draft or workspace file.