Search code examples
swiftxcodescrollviewswiftuigesture

SwiftUI: Disable button selection if scrolling within ScrollView


I'm in a pickle with SwiftUI to where I have a vertical ScrollView consisting of buttons stacked vertically. When I start scrolling, there's two outcomes:

  1. If I started scrolling when my finger was on the button, when the scroll stops, the button action fires.
  2. If I started scrolling when my finger was on the padding between the buttons, when the scroll stops, not action occurs.

My question: is there any way to prevent the button action from firing in scenario (1.) above so i.e. the button is disabled or the action is only allowed to fire when the scroll is stopped/motionless?

ScrollView(.vertical) {

    ForEach(0...5, id: \.self) { i in

        VStack(alignment: .leading, spacing: 15) {

            Button(action: {
                print("selected")
            }) {
                Text("Button \(i)")
            }
        }
    }
}

I've tried tagging the .gesture() after the code block, but it only recognizes DragGesture().onChanged() and not DragGesture().onEnded(). I've considered trying to detect the location of the drag start and cross-reference that point with the position of all button on the screen, but that seems a little excessive.

Any help, suggestions, or alternatives are appreciated!


Solution

  • Try to use view instead of a Button. With tap gesture and (maybe) gesture mask.