Search code examples
iosswiftbuttongesture

Is there a way to make a button have two separate actions depending on if it’s been tapped or long pressed?


I’m trying to make a button in Swift and make it so it does two separate actions depending on if you’ve tapped it, or long pressed it. But I also want it to open a page ONLY once you’ve released the button after holding it, and i can’t figure that out anywhere. Any help will be greatly appreciated!!

I tried using the .TapGesture and a .simultaneousGesture(LongPressGesture) and it didn’t work.


Solution

  • LongPressGesture ends when the duration of the press has reached minimumDuration, not when the finger is lifted (end of the touch).

    DragGesture does end at the end of the touch, so you can use it to detect releasing the button, and use an additional LongPressGesture to set a flag to true once it ended. You would then do one of the two different things depending on the flag.

    For example, here is an example where the button prints "Tap Action" when the touch lasts less than 2 seconds, and "Long Press Action" when the touch lasts more than 2 seconds.

    @State private var isLongPress = false
    
    ...
    
    .simultaneousGesture(
        DragGesture(minimumDistance: 0).onEnded { _ in
            if isLongPress {
                print("Long Press Action")
            } else {
                print("Tap Action")
            }
            isLongPress = false
        }
    )
    .simultaneousGesture(
        LongPressGesture(minimumDuration: 2, maximumDistance: .infinity)
            .onEnded { _ in
                isLongPress = true
            }
    )
    

    The max duration of a "tap" (as detected by TapGesture) is not documented, so you can't exactly replicate the behaviour of onTapGesture with this approach.