es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Slider de SwiftUI no interpreta doble toque con VoiceOver.

Estoy utilizando SwiftUI para construir un elemento Slider y estoy intentando usar un gesto de doble toque para restablecer su valor predeterminado. Esto funciona bien en el modo sin VoiceOver.

Según Apple (aquí), en VoiceOver, un doble toque se hace usando un triple toque. (Ver la sección “Tomar una acción en un elemento”). Sin embargo, cuando selecciono el Slider en el modo VoiceOver y hago un triple toque, escucho los tres tonos que significan “no ha sucedido nada” y mi devolución de llamada no se activa.

Mi código está abajo:

import SwiftUI

struct ContentView: View {

@State var value: Float = 0.5

var body: some View {
    VStack {
      Slider(value: self.$value, in: 0...1)
        .contentShape(Rectangle())
        .border(Color.red)
        .onTapGesture(count: 2, perform: {
          print("¡Restaurando a predeterminado!")
          self.value = 0.5
        })
    }
  }
}

He intentado agregar atributos de accesibilidad (al menos, aquellos que podrían tener sentido para mí, como allowsDirectInteraction), y nada parece habilitar esto. ¿Me estoy perdiendo algo?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Parece que solo agregar las características de accesibilidad por sí solas no resuelve el problema. Puedes intentar agregar el modificador .simultaneousGesture a tu Slider e implementar un gesto personalizado que reconozca el triple-tap para el modo VoiceOver.

    Aquí tienes un ejemplo de código que podría funcionar:

    import SwiftUI
    import UIKit
    
    struct ContentView: View {
    
        @State var value: Float = 0.5
    
        var body: some View {
            VStack {
                Slider(value: self.$value, in: 0...1)
                    .contentShape(Rectangle())
                    .border(Color.red)
                    .simultaneousGesture(TripleTapGesture().onEnded {
                        UIAccessibility.post(notification: .announcement, argument: "¡Configurando a valor predeterminado!")
                        self.value = 0.5
                    })
                    .accessibility(label: Text("Slider de valor"))
            }
        }
    }
    
    struct TripleTapGesture: Gesture {
        let tapCount = 3
        let maximumInterval = 0.3
        var sequence = GestureSequence<tapgesture>()
    
        init() {
            sequence = TapGesture(count: tapCount).sequenced(before: TapGesture(count: 1))
        }
    
        var body: some Gesture {
            sequence.simultaneously(with: DoubleTapGesture(count: tapCount - 1)
                                        .exclusively(before: sequence))
                .updating($sequence) { value, state, _ in
                    switch value {
                    case .first(true):
                        state[.first] = true
                        state[.start] = value.time
                    case .first(false), .second:
                        state = [:]
                    }
                }
                .onEnded { _ in
                    if let last = sequence.values.last, abs(last.time.timeIntervalSinceNow) < maximumInterval {
                        sequence = GestureSequence(sequence[current: .second])
                    }
                    else {
                        sequence = GestureSequence()
                    }
                }
        }
    }
    

    Este código utiliza un TripleTapGesture personalizado que reconoce un triple-tap realizado en el modo VoiceOver (filtrando los double-taps en la secuencia de gestos). Luego envía un anuncio a VoiceOver y establece tu valor en el valor predeterminado.

    ¡Espero que esto te ayude! Avísame si tienes alguna pregunta adicional.

Comments are closed.