SwiftUI: comment gérer les deux touches et appuyez longuement sur le bouton?

11

J'ai un bouton dans SwiftUI et je voudrais pouvoir avoir une action différente pour "tap button" (clic / tap normal) et "appui long".

Est-ce possible dans SwiftUI?

Voici le code simple du bouton que j'ai maintenant (ne gère que le boîtier tactile / tactile "normal").

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

J'ai déjà essayé d'ajouter un "geste longPress" mais il "exécute" toujours le clic "normal / court". Voici le code que j'ai essayé:

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

Merci!

Gérard

Gérard
la source

Réponses:

15

J'ai essayé beaucoup de choses mais finalement j'ai fait quelque chose comme ça:

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

C'est toujours un bouton avec des effets mais une pression courte et longue est différente.

norekhov
la source
3
Veuillez noter qu'à partir de Xcode 11.2.1 / iOS 13.2, la commande semble être importante ici. Utiliser onLongPressGesture()avant onTapGesture()ignorera ce dernier.
Koraktor
cela n'a pas l'animation de taper ou d'appuyer et de bloquer le codeaction
Faruk
3

Je viens de découvrir que l'effet dépend de l'ordre de l'implémentation. En mettant en œuvre la détection des gestes dans l'ordre suivant, il semble possible de détecter et d'identifier les trois gestes:

  1. gérer un double geste
  2. gérer un longPressGesture
  3. gérer un seul geste du robinet

Testé sur Xcode version 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)
        }
}
Andreas Vogel
la source
1

Ce n'est pas testé, mais vous pouvez essayer d'ajouter un LongPressGestureà votre bouton.

Cela ressemblera probablement à quelque chose comme ça.

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
la source
Salut Kilian En fait, j'aurais dû mentionner que j'avais déjà essayé d'ajouter un geste longPress mais il ne fera qu'exécuter l'action "clic normal" et non la pression longue. Éditera mon message pour l'ajouter (comme vous êtes la 2ème personne à suggérer que - le premier a supprimé sa réponse).
Gerard