Repository navigation
iOS Fabric: measureInWindow omits centered formSheet window origin #58981
Description
Description
On iOS Fabric, View.measureInWindow inside a centered native Modal with
presentationStyle="formSheet" reports coordinates relative to the Modal's React root,
without the inset UIKit gives that root when presenting the sheet. A window-level overlay
anchored with those coordinates appears at the screen's upper-left, outside the sheet.
Both portrait and landscape are affected on iPad; the full-screen iPhone presentation is
unaffected because its origin is zero.
Steps to reproduce
Minimal RNTesterPlayground.js / App.js
uses only React and React Native:
- Open the native form sheet on an iPad.
- Tap Measure in window after presentation settles.
- The red 44×44 view is 24 px right and 40 px down inside the centered sheet. Its reported
x/y omit the sheet's visible window inset (sheet-local 24/40 instead of window coordinates). - Rotate the iPad and measure again; the new inset is also absent.
- On an iPhone full-screen presentation the same path works.
Our native integration reproduced the misplaced Tooltip and Hover Card in both orientations.
The linked dependency-free reduction identifies the same measurement path; it has not been
separately executed against the latest stable RN. This report does not claim that validation.
React Native version / affected platform
0.88.0-rc.3, New Architecture / Fabric; iOS, built on macOS with Xcode 26.6 (17F113), Node
22.23.3. Integration runtime: Expo SDK 58, react-native-screens 4.28.0. The reduced playground
has no Expo or screens dependency. No crash or JS exception; this is a coordinate discrepancy.
Source diagnosis and workaround
The pinned Fabric path is NativeDOM.measureInWindow → DOM::measureInWindow →
LayoutableShadowNode::computeRelativeLayoutMetrics. The latter stops at RootNodeKind;
ModalHostViewShadowNode is such a root and its layout/state doesn't include UIKit's presented
window origin. Sources:
Resolving the actual UIView and measuring view.convert(view.bounds, to: nil) on the main
thread includes the UIKit offset. We are using a small app-owned adapter at this boundary,
without changing RN or other measureInWindow callers. Expected: measureInWindow agrees
with that UIView's UIWindow frame, including an inset presentation's origin.
Activity
react-native-bot commentedon Oct 10, 2026
Warning
Missing reproducer: We could not detect a reproducible example in your issue report. Reproducers are mandatory and we can accept only one of those as a valid reproducer:
You can read more about about it on our website: How to report a bug.