Now that both platforms observe content height natively (iOS via KVO,
Android via OnLayoutChangeListener), the JS-callable updateLayout()
is unused. Remove:
- updateLayout() and prevLayoutDetentIdentifier from iOS SheetView
- AsyncFunction("updateLayout") from both platform module definitions
- updateLayout method from the JS BottomSheetNativeComponent
Android's updateLayout() is kept as a private implementation detail
since the keyboard insets listener and native layout observer both
call it internally.
https://claude.ai/code/session_01Rp7ef1h3fKh6fhStcjqLJ5
The KVO callback was calling updateLayout(), which has two problems for
content-driven updates:
1. The prevLayoutDetentIdentifier guard can block updates. When
updateDetents triggers animateChanges, the delegate callback
sheetPresentationControllerDidChangeSelectedDetentIdentifier fires
and updates selectedDetentIdentifier to the system-assigned custom
detent identifier. On the next KVO callback, prevLayoutDetentIdentifier
(.medium) no longer matches selectedDetentIdentifier, so the update
is silently dropped.
2. Re-reading frame.size.height from the view hierarchy instead of using
the observed bounds can return a stale value during rapid layout passes.
Fix: have the KVO callback call updateDetents directly with the observed
height, bypassing both the guard and the frame re-read. The guard in
updateLayout() is preserved for the manual/fallback code path.
https://claude.ai/code/session_01Rp7ef1h3fKh6fhStcjqLJ5
Replace the async JS bridge round-trip (onLayout → updateLayout()) with
native KVO observation on the content view's bounds. When React Native's
Yoga layout engine sets the frame, the KVO callback fires synchronously
on the same run loop iteration and calls updateLayout() directly. This
eliminates the timing issues that surfaced after enabling iOS 26 design.
https://claude.ai/code/session_01Rp7ef1h3fKh6fhStcjqLJ5