How to make Buttons detect tap, double tap and long press gestures in SwiftUI
--
Ahhh taps, such an easy task. Well at least until making them work properly confused the hell out of me.
So… I see you want to code a juicy multitasking button that does an endless amount of things depending on how you touch it, yet WITHOUT sacrificing the basic Button functionality (e.g. highlight, fade out and all of that nice stuff buttons do without you asking). Something tells me you want it to perform different actions whether you tap it or press it, maybe you also want an action for a double tap, am I right?
Well, don’t you worry my child, your beloved Swift Queen is here to rescue you -again.
What you need to do is the following:
Button {
//This stays empty no matter what.
} label: {
Text("You love me")
}
//This is outside the label
.simultaneousGesture(LongPressGesture().onChanged { _ in
print("Taaap started")
})
.simultaneousGesture(LongPressGesture().onEnded { _ in
print("Taaap ended")
})
.simultaneousGesture(TapGesture(count: 2).onEnded {
print("Tap tap")
})
.simultaneousGesture(TapGesture().onEnded {
print("Tap")
})
NOTE:
For some reason, it didn’t print anything in my console. If that’s the case for you as well, just make it perform some less boring actions, they will work. 100% guaranteed.
But what’s the secret to make this work?
Ez, order the gestures by their complexity, starting with the most intricate and progressing to the simpler ones. So, for instance, if you need a LongPressGesture and a TapGesture, you’ll need to put the former before the latter. If your heart wishes to add a double tap to the equation, it will have to be placed before the single TapGesture and after the LongPressGesture, just as I showed you in my example.
The reason we choose this sequence is that the basic gestures, like the single tap, when placed before the more complex ones, cause the system to ignore the latter. For instance, if you put a double tap gesture after a single tap gesture, the former will be…