I’m trying to implement a custom sheet in SwiftUI that supports Dynamic Type and scrollable content. To handle text size increases, I wrap my content in a ScrollView
and then inject it to my custom sheet, but I’m encountering an issue with gesture priority.
The problem is that the ScrollView
‘s drag gesture takes precedence over the sheet’s drag gesture. When I try to swipe down on content at the top of the sheet, the ScrollView
‘s bounce behavior is triggered, instead of my custom “swipe down to dismiss” gesture.
Assume that the ScrollView
has a ScrollOffsetPreferenceKey
that provides its Y value as a scrollOffset
. Here’s what I am aiming for:
-
Scrolling down within the sheet (
scrollOffset
< 0) should always work smoothly. -
Scrolling up from a
scrollOffset
< 0 should allow normal scrolling past 0. -
If the user scrolls past 0 and the
scrollOffset
returns to 0, the scroll should “lock” at 0, allowing a swipe down to dismiss the sheet. -
When the
scrollOffset
is 0 (e.g., when the sheet first opens), the sheet’s drag gesture should take priority, allowing a swipe down to dismiss.
The only way I’ve found to prioritize the sheet’s drag gesture when the scrollOffset
is 0 is by setting the minimumDistance
of the drag gesture to 0. However, this disables the ScrollView
‘s scrollability, as the sheet’s drag gesture takes full control, preventing users from scrolling down within the ScrollView
.
I’ve also tried using .highPriorityGesture
and .simultaneousGesture
, but neither worked as expected.
Is it possible to achieve my desired behavior in SwiftUI, or do I need to use UIViewRepresentable
to wrap a UIScrollView
for more control over the gesture handling?