SwiftUI:ボタンのタップと長押しの両方を処理する方法?


11

SwiftUIにボタンがあり、「ボタンをタップ」(通常のクリック/タップ)と「長押し」で異なるアクションを実行できるようにしたいと考えています。

SwiftUIでそれは可能ですか?

ここに私が今持っているボタンの簡単なコードがあります(「通常の」タップ/タッチケースのみを処理します)。

Button(action: {self.BLEinfo.startScan() }) {
                        Text("Scan")
                    } .disabled(self.BLEinfo.isScanning)

「longPressジェスチャー」を追加しようとしましたが、それでも「通常/短い」クリックのみが「実行」されます。これは私が試したコードです:

Button(action: {self.BLEinfo.startScan() }) {
                        Text("Scan")
                            .fontWeight(.regular)
                            .font(.body)
                        .gesture(
                            LongPressGesture(minimumDuration: 2)
                                .onEnded { _ in
                                    print("Pressed!")
                            }
                        )
                    }

ありがとう!

ジェラール

回答:


15

私は多くのことを試しましたが、最終的に私はこのようなことをしました:

    Button(action: {
    }) {
        VStack {
            Image(self.imageName)
                .resizable()
                .onTapGesture {
                    self.action(false)
                }
                .onLongPressGesture(minimumDuration: 0.1) {
                    self.action(true)
                }
        }
    }

それはまだ効果のあるボタンですが、短押しと長押しは異なります。


3
Xcode 11.2.1 / iOS 13.2以降、ここでは順序が重要になっているようです。onLongPressGesture()before onTapGesture()を使用すると、後者は無視されます。
Koraktor

これには、コードをタップまたは押してブロックするアニメーションはありませんaction
Faruk

3

効果は実装の順序に依存することを発見しました。次の順序でジェスチャーの検出を実装すると、3つすべてのジェスチャーを検出して識別することができるようです。

  1. ダブルタップジェスチャを処理する
  2. longPressGestureを処理する
  3. シングルタップジェスチャを処理する

Xcodeバージョン11.3.1(11C504)でテスト済み

    fileprivate func myView(_ height: CGFloat, _ width: CGFloat) -> some View {
    return self.textLabel(height: height, width: width)
        .frame(width: width, height: height)
        .onTapGesture(count: 2) {
            self.action(2)
        }
        .onLongPressGesture {
            self.action(3)
        }
        .onTapGesture(count: 1) {
            self.action(1)
        }
}

1

これはテストされていませんがLongPressGesture、ボタンにを追加してみることができます。

おそらくこのようなものになるでしょう。

struct ContentView: View {
    @GestureState var isLongPressed = false

    var body: some View {
        let longPress = LongPressGesture()
            .updating($isLongPressed) { value, state, transaction in
                state = value
            }

        return Button(/*...*/)
            .gesture(longPress)
    }
}

こんにちはKilian実際に、私はすでにlongPressジェスチャーを追加しようとしたが、それでも「通常のクリック」アクションのみが「実行」され、長押しはされないことを述べたはずです。私の投稿を編集してそれを追加します(あなたが2人目の提案であるため、最初の投稿は彼の回答を削除しました)。
Gerard、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.