Skip to content

fix(ios): keep non-draggable sheets from being swiped away - #927

Merged
lodev09 merged 3 commits into
lodev09:mainfrom
maxlapides:fix/ios-non-draggable-swipe-dismiss
Oct 15, 2026
Merged

lodev09 merged 3 commits into
lodev09:mainfrom
maxlapides:fix/ios-non-draggable-swipe-dismiss

Conversation

@maxlapides

Copy link
Copy Markdown
Contributor

Summary

With draggable={false}, the user can't drag or resize a sheet, but on iOS pulling down on its scrollable still dismisses it when dismissible is true. UIKit asks presentationControllerShouldDismiss: both for that scroll-edge pull and for a tap on the dim, and TrueSheet answered with dismissible alone.

A non-draggable sheet now refuses a dismissal while a pan is under way, so it can't be swiped or pulled away. Tapping outside it still dismisses it, and dismiss() is unaffected. The refused pull isn't reported as onDismissAttempt, since the sheet is dismissible.

Draggable sheets and dismissible={false} sheets behave as before.

presentationControllerShouldDismiss: is the same on v3, and the fix applies there too, minus the onDismissAttempt part (v3 doesn't have that event). Happy to open the v3 backport.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Test Plan

Bare example, iPhone 17 Pro simulator (iOS 26.5). Locally, the map screen's ScrollView sheet got draggable={false} and lost its refresh control, so a pull at the top reaches the sheet.

main:

  • Before: pulling the list down from the top dismisses the sheet.
  • After: the same pull, and a fast one from the header, leave it presented. Tapping above the sheet dismisses it.
  • onDismissAttempt doesn't fire for the refused pull. With dismissible={false} added, the same pull fires it as before.
  • Prompt sheet (draggable): still swipes away.

v3 (3.11.18), same change without the onDismissAttempt part:

  • The pull leaves the sheet presented, and tapping above it dismisses it.

Checklist

  • I tested on iOS
  • I tested on Android
  • I tested on Web
  • I updated the documentation (if needed)
  • I added a changelog entry (if needed)

With draggable set to false, pulling down on the sheet's scroll view still
dismissed it when dismissible was true. Refuse a dismissal while a pan is
under way on a non-draggable sheet, so only a tap outside it dismisses it,
and don't report that refusal as onDismissAttempt.
@vercel

vercel Bot commented Oct 14, 2026

Copy link
Copy Markdown

@maxlapides is attempting to deploy a commit to the lodev09 Team on Vercel.

A member of the Team first needs to authorize it.

@maxlapides
maxlapides marked this pull request as ready for review October 14, 2026 21:43
UIKit skips didAttemptToDismiss for a short pull, so the flag stayed set and
swallowed the next onDismissAttempt (e.g. after dismissible turned false).
@lodev09

lodev09 commented Oct 15, 2026

Copy link
Copy Markdown
Owner

Thanks @maxlapides! Verified on iOS 27: the pull is refused, the dim tap still dismisses, and the refused pull doesn't fire onDismissAttempt.

Pushed one fix (0e9d5ce): _refusedPanDismiss could go stale. UIKit asks shouldDismiss when a pull starts but only calls didAttemptToDismiss if the pull goes far enough, so a short pull left the flag set. If dismissible then flips to false (unsaved changes), the next pull's onDismissAttempt gets swallowed. It also survives re-presenting, since the controller is reused.

Repro: draggable={false}, short pull at the top of the list, set dismissible={false}, full pull → no onDismissAttempt.

The flag is now set on every shouldDismiss call.

@vercel

vercel Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
react-native-true-sheet Ready Ready Preview Oct 15, 2026 2:48pm UTC

Request Review

@lodev09
lodev09 merged commit ce52b78 into lodev09:main Oct 15, 2026
6 checks passed

This branch was successfully deployed

1 active deployment
Preview — 0e9d5ce6 Deployed Oct 15, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants