Repository navigation
Description
Before submitting a new issue
- I tested using the latest version of the library.
- I tested using a supported version of React Native.
- I checked for existing issues that might answer my question.
Bug Summary
When a sheet is presented over another sheet that stays presented, and its content changes size just after it presents, dismissing it within about half a second leaves the sheet underneath missing for several frames once the top sheet is down. The sheet underneath then pops back.
Affected Platforms
- iOS
- Android
- Web
- Other
Library Version
4.0.1
Environment Info
info Fetching system and libraries information...
System:
OS: macOS 27.0.1
CPU: (10) arm64 Apple M1 Pro
Memory: 174.22 MB / 32.00 GB
Shell:
version: "5.9"
path: /bin/zsh
Binaries:
Node:
version: 26.4.0
path: /opt/homebrew/bin/node
Yarn:
version: 1.22.22
path: /opt/homebrew/bin/yarn
npm:
version: 11.17.0
path: /opt/homebrew/bin/npm
Watchman: Not Found
Managers:
CocoaPods:
version: 1.17.0
path: /opt/homebrew/lib/ruby/gems/4.0.0/bin/pod
SDKs:
iOS SDK:
Platforms:
- DriverKit 27.0
- iOS 27.1
- macOS 27.0
- tvOS 27.0
- visionOS 27.0
- watchOS 27.0
Android SDK:
API Levels:
- "28"
- "29"
- "30"
- "31"
- "32"
- "33"
- "34"
- "35"
- "36"
- "37"
Build Tools:
- 28.0.3
- 29.0.2
- 30.0.2
- 30.0.3
- 31.0.0
- 32.0.0
- 33.0.0
- 33.0.1
- 34.0.0
- 35.0.0
- 36.0.0
- 37.0.0
System Images:
- android-29 | Intel x86 Atom
- android-29 | Intel x86 Atom_64
- android-30 | Intel x86_64 Atom
- android-30 | Google APIs ARM 64 v8a
- android-31 | ARM 64 v8a
- android-32 | Google APIs ARM 64 v8a
- android-32 | Google Play ARM 64 v8a
- android-32 | Google Play Intel x86 Atom_64
- android-33 | Google APIs ARM 64 v8a
- android-35 | Google Play ARM 64 v8a
- android-36 | Google Play ARM 64 v8a
- android-37.2-beta3 | 16 KB Page Size Google Play ARM 64 v8a
Android NDK: Not Found
IDEs:
Android Studio: 2026.1 AI-261.26222.65.2613.16025427
Xcode:
version: 27.1/27A9275
path: /usr/bin/xcodebuild
Languages:
Java:
version: 17.0.1
path: /usr/bin/javac
Ruby:
version: 4.0.5
path: /opt/homebrew/opt/ruby/bin/ruby
npmPackages:
"@react-native-community/cli": Not Found
react:
installed: 19.3.0
wanted: 19.3.0
react-native:
installed: 0.88.1
wanted: 0.88.1
react-native-macos: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: Not found
newArchEnabled: Not found
iOS:
hermesEnabled: Not found
newArchEnabled: Not foundSteps to Reproduce
- In the repro, open the screen "Stacked sheets". The parent sheet has
detents={['auto', 1]},dismissible={false}anddimmed={false}. The child hasdetents={[1]}and adds a 40 pt view to its content inonDidPresent. - Turn on "Child content grows once presented".
- Tap "Cycle 10 times". It presents the child and dismisses it 250 ms after
onDidPresent, ten times.
Expected: the parent sheet is there as soon as the child slides off it.
Actual: once the child is down, the parent is missing for several frames each time, then reappears all at once. With the switch off, it's there the moment the child uncovers it.
Repro
https://github.com/philiplindberg/true-sheet-repros
Additional Context
Expo SDK 58, React Native 0.88, new architecture, 4.0.1 with no patches. In a screen recording of the iPhone 18 Pro simulator (iOS 27), the parent's button stayed hidden 1.02–1.04 s per cycle with the switch on and 0.96–0.97 s with it off, over ten cycles each. In our app on an iPhone 18 Pro (iOS 27), a form sheet whose content settles just after it presents did this on 8 of 10 swipe dismissals.
What happens: when the child fully covers the parent, UIKit hides the parent (alpha 0 on its UIDropShadowView) in a layout of the presentation stack, and shows it again (alpha 1, not animated) when a dismissal starts. Normally the hide is instant. Here the child's content grows after it presents, so setupSheetDetentsForSizeChange runs on the child, which has no 'auto' or 'peek' detent, and calls invalidateDetentsAnimated. The first layout of the stack after the present then runs inside animateChanges, so UIKit's hide becomes an animation of about 0.5 s. If the dismissal starts before it ends, the unanimated alpha 1 changes only the model value, and the hide animation goes on drawing the parent at opacity 0 until it finishes.
A fix: in setupSheetDetentsForSizeChange, invalidate only when the sheet has an 'auto' or 'peek' detent, the only ones that resolve from those heights:
if (![self.detents containsObject:@(-1)] && ![self.detents containsObject:@(-2)]) {
return;
}With that, in our app the hide is instant again and the parent no longer goes missing (0 of 9 dismissals on 4.0.0, 0 of 8 on 4.0.1). It doesn't cover a sheet with an 'auto' or 'peek' detent that resizes just after presenting over another sheet, since that one still invalidates animated; a fuller fix might keep the stack's layout out of animateChanges. Happy to open a PR for either.
Activity
github-actions commentedon Oct 30, 2026
Hey @philiplindberg! Thanks for opening the issue.
It looks like your issue is missing a valid reproduction link.
A minimal reproduction helps us investigate and fix the issue faster. Without one, we may not be able to help.
Please provide one of the following:
See "How to create a Minimal, Reproducible Example" for more guidance.
You can edit your original issue or leave a comment with the repro link. Issues without reproductions may be closed after 14 days.
github-actions commentedon Oct 30, 2026
Thank you for providing a repro! We'll take a look at this issue soon.