LongPressGesture | Apple Developer Documentation
A gesture that succeeds when the user performs a long press.
https://developer.apple.com/documentation/swiftui/longpressgesture
Handling long-press gestures | Apple Developer Documentation
Detect extended duration taps on the screen, and use them to reveal contextually relevant content.
https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/handling_uikit_gestures/handling_long-press_gestures
1. Base structure
var body: some View {
VStack {
Rectangle()
.fill(.blue)
.frame(maxHeight: 100)
.frame(width: 55)
.frame(maxHeight: .infinity, alignment: .bottom)
.padding()
HStack {
Text("PRESS HERE")
.padding()
.glassBackgroundEffect()
Text("RESET")
.padding()
.glassBackgroundEffect()
}
}.padding()
}
struct ContentView: View {
@State private var isComplete: Bool = false
@State private var isSuccess: Bool = false
var body: some View {
VStack {
progressRectangle
buttonStack
}
.padding()
}
private var progressRectangle: some View {
Rectangle()
.fill(isSuccess ? Color.green : Color.blue)
.frame(maxHeight: isComplete ? .infinity : 0)
.frame(width: 55)
.frame(maxHeight: .infinity, alignment: .bottom)
.padding()
}
private var buttonStack: some View {
HStack{
pressHereButton
resetButton
}
}
private var pressHereButton: some View {
Text(isSuccess ? "SUCCESS" : "PRESS HERE")
.padding()
.onLongPressGesture(minimumDuration: 3.0, maximumDistance: 50) { isPressing in
if isPressing {
animate {
isComplete.toggle()
}
} else {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1){
if !isSuccess {
animate {
isComplete = false
}
}
}
}
} perform: {
animate {
isSuccess = true
}
}
}
private var resetButton: some View {
Text("RESET")
.padding()
.onTapGesture {
isComplete = false
isSuccess = false
}
}
private func animate(_ action: @escaping () -> Void) {
withAnimation(.easeInOut(duration: 3.0), action)
}
}
- onLongPressGesture: This is the core interaction:
minimumDuration: 3.0
means the press needs to last at least 3 seconds.
maximumDistance: 50
means the finger can't move more than 50 points during the press.
- Two blocks of code:
- Start of Press: The
isPressing
block triggers when the gesture starts and meets the minimum duration:- The
isComplete
variable is toggled (flipped between true and false) using an animation to make the rectangle grow smoothly.
- The
- End of Press: The second block triggers when the gesture ends. If the action hasn't succeeded (
!isSuccess
) it resets theisComplete
variable after a slight delay (DispatchQueue.main.asyncAfter
).
- Start of Press: The
- Gesture Completion (perform:): If the gesture meets all requirements, this block runs and sets
isSuccess
to true,also with an animation.