Skip to content

[RNTester][iOS] Add tab bar controller, minimally support iPhone Duo - #58664

Open
huntie wants to merge 1 commit into
react:mainfrom
huntie:rntester-native-navigator
Open

huntie wants to merge 1 commit into
react:mainfrom
huntie:rntester-native-navigator

Conversation

@huntie

@huntie huntie commented Sep 24, 2026 •

Copy link
Copy Markdown
Collaborator

Summary:

Migrates RNTester on iOS from a single React Native entry point to a native UITabBarController stack — allowing us to leverage the platform tab bar, header, and safe area behaviours needed to support iPhone Duo.

Android is unchanged. No new capabilities are added to React Native itself.

image

Motivation

RNTester on iOS runs as one React Native surface that draws its own header and bottom tab bar in JS, so it cannot follow platform layouts such as iPhone Duo's, where the status bar sits in a side cutout and the tab bar moves to the side.

Necessary and intentional fork: Fork the iOS RNTester app to a native navigation setup, which gives RNTester the platform tab bar, header and back gesture, minimally supports iPhone Duo, and takes the brownfield shape many apps embed React Native in.

  • This avoids us from touching <SafeAreaView> in core at this stage, or making any hardcoded hacks to the custom tab bar — which had already drifted into buggy territory on the regular iPhone.
  • The navigator is written inline rather than taken from a library such as react-native-screens, to avoid introducing a dependency within core (against main).

Changes

  • Add a UITabBarController holding Components, APIs and Playground, each a UINavigationController stack; every tab root and pushed module or example mounts its own RNTesterScreen surface, kept within the safe area.
  • Push screens from JS through a small RNTesterNavigator module, and share Recently Viewed across surfaces.
  • Cap the module list and example frames at 600pt wide, on all platforms.
  • Move Playground to the last tab, on both platforms.

⚠️ Key tradeoff

Out-of-tree platforms: On iOS, RNTester is no longer a single React Native surface, so platforms reusing its JS will need equivalent native wiring for the main pages. The single-surface RNTesterApp stays registered, and Android is entirely unchanged.

Notes

resolveExampleURL is extracted from RNTesterAppShared in this PR rather than a separate one: it exists only so both shells share the deep link parsing, and the navigator is what needs it.

Changelog: [Internal]

Test Plan:

xcodebuild -workspace packages/rn-tester/RNTesterPods.xcworkspace -scheme RNTester -configuration Debug -destination 'platform=iOS Simulator,name=iPhone 18 Pro' build
  • ✅ RNTester builds for iOS Simulator and runs on iPhone 18 Pro (iOS 27.0) and iPhone Duo (iOS 27.1).
  • ✅ Tabs switch, including by the apis-tab test ID the Maestro flow uses; modules and examples push with native back and the docs button; Recently Viewed updates on the list.
  • ✅ Deep links open the target on the Components tab, warm (rntester://example/Switch) and at cold launch (rntester://example/Image).
  • ✅ iPhone Duo: each screen stays within the safe area, folded and unfolded; the list and example frames cap at 600pt when unfolded.
  • ✅ Android: RNTester runs on an emulator with its single surface, and the tabs read Components, APIs, Playground.
  • ⚠️ Not run: Maestro.
iPhone 18 Pro iPhone 18 Pro, module iPhone Duo, folded Android
Native tab bar and header; Playground moves to the last tab Pushed module screen with native back and docs buttons Content within the safe area, clear of the side cutout and tab bar (Unchanged)
iPhone Duo, unfolded
Max content width applied

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Sep 24, 2026
@huntie
huntie force-pushed the rntester-native-navigator branch from 8e1f4ce to 136bc6d Compare September 24, 2026 10:47
@huntie
huntie marked this pull request as ready for review September 24, 2026 12:17
@facebook-github-tools facebook-github-tools Bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Sep 24, 2026
@javache

javache commented Sep 24, 2026

Copy link
Copy Markdown
Contributor

Switching to multi-root is a pretty big change, and we should probably discuss the consequences a bit more.

Can we do something similar to react-native-screens and keep everything in a single root?

@huntie

huntie commented Sep 24, 2026 •

Copy link
Copy Markdown
Collaborator Author

@javache We can, but while depending on react-native-screens in core (even for our example app), which against main, will likely be a headache. This is essentially optional-mount-three-views as compat, which becomes the default pattern for the iOS version of RNTester.

Unless we patch or depend on at least a suitable SafeAreaView in core, this is a pragmatic way to opt out of solving these concerns, IMO.

@javache

javache commented Sep 24, 2026

Copy link
Copy Markdown
Contributor

Yeah, not suggesting we adopt react-native-screens here (just to keep rntester simple), just suggesting we consider the alternative of building a very basic native component that wraps similar logic, so we can keep this as a single root.

@cortinico

Copy link
Copy Markdown
Contributor

just suggesting we consider the alternative of building a very basic native component that wraps similar logic, so we can keep this as a single root.

+1 to this.

I also don't think we should optimize RNTester for iPhone Duo. We haven't optimized it for Android Foldable devices either. We run e2e tests on this app so the simpler it is to maintain, the better.

@huntie

huntie commented Sep 25, 2026

Copy link
Copy Markdown
Collaborator Author

I think I'll be able to push an update that keeps the single root design from the JS point of view 👍🏻 Due next week.

@cortinico Disagree. It's reasonable to make our tester app usable, and before this diff we already had UX bugs on regular iPhones. It's also not, theoretically, out of scope for core to implement some incoming foldable APIs/behaviours, so it's nice to at least view RNTester on a foldable without blatant safe area bugs. (Aware we will probably try to add these APIs via other libraries, but it's not fundamentally off the table.)

If we support iOS, it's worth having a trivial navigation setup for our iOS tester app — especially if it saves maintaining custom UI code.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants