# feat\(mobile\): thread header minimizes on the Duo while reading back through history · PR \#24235 · pingdotgg/t3code

[View on GitCafe](https://git.cafe/pingdotgg/t3code/pull/24235)

Repository: [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code)

Visibility: public

State: merged

Source repository: pingdotgg/t3code

Source branch: t3code/thread-header-minimization

Target branch: main

Head commit: 106459045a52aba28b8bca8e3e8317773357a952

[Discussion and reviews](https://git.cafe/pingdotgg/t3code/pull/24235)

[Commits](https://git.cafe/pingdotgg/t3code/pull/24235/commits?format=markdown)

[Files changed](https://git.cafe/pingdotgg/t3code/pull/24235/diffs?format=markdown)

## Description

---

On the iPhone Duo, Messages tucks its navigation bar away while you scroll back through a conversation and brings it back when you reverse. The Duo's short display needs that room, but T3 Code's thread header stayed fixed.

iOS 27 adds `UINavigationItem.navigationBarMinimization` for this, and our Screens fork already exposes it as the header's `minimizationBehavior` (upstream software-mansion/react-native-screens#4703). The thread route now opts in with `onScrollUp` through a new `unstable_headerMinimizationBehavior` screen option, applied on the Duo only:

- **Everything that doesn't opt in** falls back to `automatic`, the system default. On other iPhones and the iPad, iOS 27.0 resolves that to never minimizing.
- **Other screens on the Duo:** the system default there is to minimize on scroll down, so Home and the PR lists now hide their header too, like other apps on the Duo. That's new, because their scroll views now register (see below).

Setting the prop alone did nothing, because UIKit only minimizes against a scroll view registered with the screen's controller:

- The feed's scroll view is now wrapped in a `ScrollViewMarker` (via `KeyboardChatScrollView`'s `ScrollViewComponent`), because the composer and overlays beside it stop UIKit from finding it on its own.
- Every workspace route is hosted in `Split.Screen`, which ignored marker registration. Screens `5.0.0-t3.37` ([pingdotgg/react-native-screens#4](https://github.com/pingdotgg/react-native-screens/pull/4)) makes it register the scroll view with its controller, like stack screens do. Merge that fork PR with a merge commit together with this one.

This needs a new native build; an OTA update alone won't enable it. Android is unaffected.

## Evidence

iPhone Duo (iOS 27.1 simulator, folded): the header minimizes when scrolling back through history; the vertical bar's items stay.

https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/53ade706c077fa3d/duo-after.mp4

These two clips predate the Duo-only gating. They show the same scripted scroll on an iPhone 18 Pro (iOS 27.0) simulator, before and after `Split.Screen` registration. Before, the header stays:

https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/419a409c707d58c8/before.mp4

After, the header minimizes on scroll up and restores on the reverse scroll:

https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/e82df838bf4c27b1/after.mp4

With the gating, the iPhone 18 Pro is back to the fixed header, which I re-checked on the simulator. The unfolded Duo wasn't recorded.

🤖 Generated with [Claude Code](https://claude.com/claude-code) (Claude Opus 5.5)

