👆Long Press
SwiftUI ⟩ Gestures ⟩ Long Press
⭐️ .onEnded()
- 只有時間按超過 - minimumDuration才會觸發❗️
- if the user stops touching the view before - minimumDurationseconds have elapsed or moves their finger more than- maximumDistancepoints 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,所以這是否表示此參數根本無用❓」
Last updated
Was this helpful?