SwiftUI 处理 button/view onTapGesture 和 onLongPressGesture with a release action

SwiftUI handling button/view with onTapGesture and onLongPressGesture with a release action

我有一个同时具有 onTapGesture 和 onLongPressGesture 的视图。问题是我的 onLongPressGesture 的实现阻止了 onTapGesture 被调用。

这是一些代码

View()
      .onTapGesture {
           action_1
       }
      .onLongPressGesture(minimumDuration: 0.5, maximumDistance: 10, pressing: {
                                    pressing in
                                    self.isPressing = pressing
                                    if (pressing) {action_2}
                                    if !pressing {action_3}
                                }, perform: {})

.onLongPressGesture 中的 pressing 参数检测用户是否按下 view/button,并且将始终执行 .onLongPressGesture,无论 minimumDuration 是多少。

编辑

Snapchat shutter where you can tap to take a picture, hold the button to start recording a video, then release the button to stop recording the video. That is why there are three actions that need to be performed.

这很棘手。这是我所做的:

  1. onTapGesture,对于点击手势
  2. LongPressGesture,延迟 0.5 秒。 0.5 秒结束后 (.onEnded),开始录制。
  3. DragGesture,用于观察手指离开屏幕的时间。遇到这种情况,请停止录制。
struct ContentView: View {
    
    /// for visual indicators
    @State var recording = false
    @State var tapped = false
    
    var body: some View {
        let longPressDrag = LongPressGesture(minimumDuration: 0.5) /// 2.
            .onEnded { _ in /// 0.5 seconds is over, start recording
                print("Long press start")
                recording = true
            }
            .sequenced(before: DragGesture(minimumDistance: 0)) /// 3.
            .onEnded { _ in /// finger lifted, stop recording
                print("Long press release")
                recording = false
            }
        
        Circle()
            .fill(recording ? Color.red : Color.blue)
            .opacity(tapped ? 0.5 : 1)
            .frame(width: 100, height: 100)
            
            .onTapGesture { /// 1.
                print("Tapped")
                
                tapped = true
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { tapped = false }
            }
            .gesture(longPressDrag)

    }
}

结果:


旧答案: pressing 参数不用于执行 action_2 等操作。可以,但它更常用于更改 @State,例如在按下时以绿色突出显示视图。您可以在 community documentation.

中找到更多信息

相反,您可能想要的是在 perform 闭包中调用您的操作 (action_2/print("long"))。

struct ContentView: View {
    var body: some View {
        Text("Hi")
            .font(.title)
            .onTapGesture {
                print("tap")
            }
            .onLongPressGesture(minimumDuration: 0.5, maximumDistance: 10) {
                print("long")
            }
    }
}

结果: