SwiftUI: ¿cómo manejar AMBOS toque y pulsación larga del botón?

11

Tengo un botón en SwiftUI y me gustaría poder tener una acción diferente para "botón de toque" (clic / toque normal) y "pulsación larga".

¿Es eso posible en SwiftUI?

Aquí está el código simple para el botón que tengo ahora (maneja solo el caso de toque / toque "normal").

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

Ya traté de agregar un "gesto de LongPress" pero todavía solo "ejecuta" el clic "normal / corto". Este fue el código que probé:

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

¡Gracias!

Gerard

Gerard
fuente

Respuestas:

15

Intenté muchas cosas pero finalmente hice algo como esto:

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

Sigue siendo un botón con efectos, pero presionar breve y largamente es diferente.

norekhov
fuente
3
Tenga en cuenta que a partir de Xcode 11.2.1 / iOS 13.2, el orden parece ser importante aquí. Usar onLongPressGesture()antes onTapGesture()ignorará el último.
Koraktor
esto no tiene la animación de tocar o presionar y bloquear el códigoaction
Faruk
3

Acabo de descubrir que el efecto depende del orden de implementación. Al implementar la detección de gestos en el siguiente orden, parece posible detectar e identificar los tres gestos:

  1. manejar un gesto de doble toque
  2. manejar una LongPressGesture
  3. manejar un solo toque

Probado en Xcode versión 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
fuente
1

Esto no se ha probado, pero puede intentar agregar un LongPressGesturebotón a su botón.

Presumiblemente se verá algo así.

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
fuente
Hola Kilian En realidad, debería haber mencionado que ya había intentado agregar un gesto de LongPress, pero aún así solo "ejecutará" la acción de "clic normal" y no la pulsación larga. Editaré mi publicación para agregar eso (ya que usted es la segunda persona que sugiere eso, la primera eliminó su respuesta).
Gerard