👆Long Press
Last updated
Last updated
SwiftUI ⟩ Gestures ⟩ Long Press
⭐️ .onEnded()
只有時間按超過 minimumDuration
才會觸發❗️
if the user stops touching the view before minimumDuration
seconds have elapsed or moves their finger more than maximumDistance
points SwiftUI does not invoke the onEnded(_:)
callback.
⭐️ .onChanged()
只要摸到,就會觸發,但「只觸發一次」,就算摸再久,也只觸發一次,不會連續觸發,附送的 value
總是 true
。但「每摸一次,就觸發一次」。
📗 參考:Mastering SwiftUI, Ch. 17: Using Gestures (p.371)
import SwiftUI
struct ContentView: View {
// star image size state (true: small, false: big)
@State private var isSmallStar = false
// ⭐️ `@GestureState` tracks the state change of a gesture
// `isStarPressed` indicates whether a tap event is detected
@GestureState private var isStarPressed = false
var body: some View {
Image(systemName: "star.circle.fill")
.font(.system(size: 200))
// ⭐️ dimmer when star is pressed
.opacity(isStarPressed ? 0.4 : 1)
.scaleEffect(isSmallStar ? 0.5 : 1.0)
.animation(.easeInOut)
.foregroundColor(.yellow)
.overlay(
Text(verbatim: "\(isStarPressed)")
.foregroundColor(isStarPressed ? .pink : .secondary)
)
.gesture(
LongPressGesture(minimumDuration: 1.0)
// on pressed: (tap and hold)
// ⭐️ update `@GestureState` var as the gesture's value changes.
// • value: LongPressGesture.Value == Bool (current value)
// gesture's current value (`true` indicates a tap is detected)
// • state: inout State == Bool (previous gesture's value)
// `state` == `isStarPressed` in this case
// • transaction:
// stores the "context"(?) of the gesture.
.updating($isStarPressed) { (value, state, _) in
// ⭐️ save current value (is pressed or not?)
state = value
}
// on long pressed:
// • value: LongPressGesture.Value == Bool (gesture's final value)
// 🔸 註:
// 只有時間超過 `minimumDuration` 才會引發 onEnded❗️
// 而且 `isStarPressed` 會馬上變為 false❗️
.onEnded { _ in
// ⭐️ toggle image size when long pressed
isSmallStar.toggle()
}
)
}
}
Design+Code ⟩ SwiftUI Long Press Gesture and Tap Progress Animation
use GestureState to track gesture's state.
問:「 Long Press Gesture 的 onEnded { finished in ... }
事件處理程序會接收一個 finished 參數,但問題是:onEnded 是在真正「觸發長按」時才會執行,而此時 finished 參數似乎總是 true,所以這是否表示此參數根本無用❓」