簡體   English   中英

SwiftUI 處理帶有釋放動作的 onTapGesture 和 onLongPressGesture 的按鈕/視圖

[英]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: {})

pressing 參數 in.onLongPressGesture 檢測用戶是否按下視圖/按鈕,並且將始終執行 the.onLongPressGesture,無論 minimumDuration 是多少。

編輯

您可以點擊Snapchat 快門拍照,按住按鈕開始錄制視頻,然后松開按鈕停止錄制視頻。 這就是為什么需要執行三個操作的原因。

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

  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)

    }
}

結果:

Snapchat 風格的按鈕

舊答案: action_2 pressing的操作。 你可以,但它更常用於更改@State ,例如在按下視圖時以綠色突出顯示視圖。 您可以在社區文檔中找到更多信息。

相反,您可能想要的是在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")
            }
    }
}

結果:

點擊和長按都可以工作

XCode 14. Swift 5我已將這兩個手勢添加到圖像視圖中。 點擊手勢圖像將縮放和取消縮放。 在 LongPressGesture 上圖像背景顏色會改變。 提供 count: 2 使其成為 doubleTapGesture。

struct ContentView: View {
// MARK: - Property

@State private var isAnimating: Bool = false
@State private var imageScale: CGFloat = 1
@State private var shadowColor: Color = .black

// MARK: - Content
var body: some View {
    NavigationView {
        ZStack {
            Image("magazine-front-cover")
                .resizable()
                .aspectRatio(contentMode: .fit)
                .cornerRadius(8)
                .padding()
                .shadow(color: shadowColor, radius: 22, x: 2, y: 2)
                .opacity(isAnimating ? 1 : 0)
                .animation(.linear(duration: 1), value: isAnimating)
                .scaleEffect(imageScale)
            // MARK: - 1. Tap Gesture
                .onTapGesture(count: 1, perform: {
                    if imageScale == 1 {
                        withAnimation(.spring()) {
                            imageScale = 5
                        }
                    } else {
                        withAnimation(.spring()) {
                            imageScale = 1
                        }
                    }
                })
            // MARK: - 2. LongPress Gesture
                .onLongPressGesture(perform: {
                    if shadowColor == .black {
                        shadowColor = .green
                    } else {
                        shadowColor = .black
                    }
                })
        }
        .ignoresSafeArea(edges: .all)
        .navigationTitle("Pinch & Zoom")
        .navigationBarTitleDisplayMode(.inline)
        .onAppear {
                isAnimating = true
        }
    } // END of Navigation View
  }
}

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM