So I have a ScrollView
holding a set of views:
ScrollView { ForEach(cities) { city in NavigationLink(destination: ...) { CityRow(city: city) } .buttonStyle(BackgroundButtonStyle()) } }
In every view I have a drag gesture:
let drag = DragGesture() .updating($gestureState) { value, gestureState, _ in // ... } .onEnded { value in // ... }
Which I assign to a part of the view:
ZStack(alignment: .leading) { HStack { // ... } HStack { // ... } .gesture(drag) }
As soon as I attach the gesture, the ScrollView
stop scrolling. The only way to make it scroll it to start scrolling from a part of it which has no gesture attached. How can I avoid it and make both work together. In UIKit is was as simple as specifying true
in shouldRecognizeSimultaneouslyWith
method. How can I have the same in SwiftUI?
In SwiftUI I've tried attaching a gesture using .simultaneousGesture(drag)
and .highPriorityGesture(drag)
– they all work the same as .gesture(drag)
. I've also tried providing all possible static GestureMask
values for including:
parameter – I have either scroll working or my drag gesture working. Never both of them.
Here's what I'm using drag gesture for:
We will use SimultaneousGesture and DragGesture to disable scrolling. We will set DragGesture's minimum distance to 0, which will disable the drag gesture to stop the scroll behavior.
A property wrapper type that updates a property while the user performs a gesture and resets the property back to its initial state when the gesture ends.
If you want to programmatically make SwiftUI's List move to show a specific row, you should embed it inside a ScrollViewReader . This provides a scrollTo() method on its proxy that can move to any row inside the list, just by providing its ID and optionally also an anchor.
You can set minimumDistance to some value (for instance 30). Then the drag only works when you drag horizontally and reach the minimum distance, otherwise the scrollview or list gesture override the view gesture
.gesture(DragGesture(minimumDistance: 30, coordinateSpace: .local)
Just before
.gesture(drag)
You can add
.onTapGesture { }
This works for me, apparently adding a tapGesture avoids confusion between the two DragGestures.
I hope this helps
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With