Tocar en UISlider evita el desplazamiento de UIScrollView

Tengo un UISlider (vertical) dentro de un UIScrollview. Me gustaría poder cambiar el valor del control deslizante y, sin levantar el dedo, desplazar la vista de desplazamiento hacia la izquierda o hacia la derecha.

Comportamiento deseado:

Toque hacia abajo dentro del UISlider vertical, seguido de un dedo arrastrando hacia la izquierda o hacia la derecha hace que la vista de desplazamiento se desplace

Comportamiento real:

Tocar hacia abajo dentro del UISlider vertical, seguido de un arrastre con el dedo hacia la izquierda o hacia la derecha no provoca ningún movimiento en UIScrollview. un toque abajo afuera el UISlider seguido de un arrastre desplazará la vista de desplazamiento como se esperaba

UIView tiene una propiedad llamada exclusiveTouch que parece estar relacionada con mi problema. Intenté configurarlo en NO, sin suerte.

Entonces, ¿cómo se pueden configurar mis UISliders para que la vista de desplazamiento debajo de ellos responda a los toques que se originan dentro de los UISliders?

preguntado el 12 de junio de 12 a las 21:06

+1 para el resultado deseado/esperado frente al resultado real. Más preguntas deberían hacer esto. -

5 Respuestas

¿Has intentado subclasificar UIScrollView y la aplicación de - (BOOL)touchesShouldCancelInContentView:(UIView *)view? Según la documentación de Apple:

// called before scrolling begins if touches have already been delivered to a subview of the scroll view. if it returns NO the touches will continue to be delivered to the subview and scrolling will not occur
// not called if canCancelContentTouches is NO. default returns YES if view isn't a UIControl

Si simplemente regresas NO si el view es tuyo UISlider, esta puede haz lo que quieras, asumiendo tu UIScrollView solo se desplaza horizontalmente. Si esto no funciona, probablemente tendrá que hacer un manejo táctil personalizado (es decir, anular touchesBegan:withEvent:, touchesChanged:withEvent:, etc.) tanto para su UIScrollView y su UISlider.

Respondido el 18 de junio de 12 a las 05:06

Lo que está viendo es el comportamiento previsto.

Cada evento táctil solo es manejado por un control. Qué exclusiveTouch en realidad es para prevenir otros toque los eventos para que no se entreguen a otras vistas.

Para hacer lo que estás tratando de hacer, tendrías que hacer algo del manejo táctil tú mismo. Pasar el evento a ambas vistas. Podrías hacerlo implementando todos los touchesBegan:, touchesMoved: etc. métodos y pasar los eventos a ambas vistas. Puede leer más sobre ese enfoque en el Documentación de UIResponder. Otro enfoque es hacer el manejo de eventos en un UIGestureRecognizer en la vista de desplazamiento que prueba el control deslizante y actualiza el valor del control deslizante usando el y-delta. Puede leer más sobre los reconocedores de gestos y el manejo de eventos en la sección sobre Reconocedores de gestos en la Guía de manejo de eventos para iOS.


Nota al margen:

Vaya a la aplicación Configuración y cambie un interruptor a la mitad (por ejemplo, el modo Avión) y luego arrastre hacia abajo. Nada pasará. El resto del sistema operativo se comporta de la misma manera. ¿Estás seguro de que esta es la interacción que realmente quieres hacer? Las aplicaciones que se comportan de manera diferente a menudo se sienten raras y desconocidas.

Respondido el 20 de junio de 20 a las 10:06

+1 para "Para hacer lo que estás tratando de hacer, tendrías que manejar algo del tacto". - códigos morgan

@morgancodes Sí, probablemente un poco vago. Agregué dos alternativas básicas y enlaces a documentación relevante sobre cómo hacer su propio manejo táctil. - David Rönnqvist

Tu pregunta me confundió un poco. Está diciendo un control deslizante vertical, pero ¿arrastrar hacia la izquierda y hacia la derecha?

Si desea desplazar la vista de desplazamiento al arrastrar el UISlider, la forma correcta de hacerlo es

[mySlider addTarget:self action:@selector(sliderMoved:) forControlEvents:UIControlEventValueChanged];

y

- (void) sliderMoved:(UISlider*) slider {
    myScrollView.contentOffset.x = slider.value * (myScrollView.contentSize.width - myScrollView.bounds.size.width);
}

Espero que esto sea lo que quieres.

Respondido el 15 de junio de 12 a las 02:06

Gracias por tu respuesta, pero esto no es lo que estoy preguntando. Estoy tratando de descubrir cómo permitir que el evento touchesMoved se aplique a UIScrollview, no solo al UISlider dentro de la vista de desplazamiento. Quiero un arrastre vertical para cambiar el valor del control deslizante y un arrastre horizontal para cambiar la posición de UIScrollview, como lo haría si no hubiera un control deslizante vertical en el camino. - códigos morgan

Debe configurar delaysContentTouches como NO y evitar que los objetos UISlider se desplacen, verifique el código a continuación.

mySlider.delaysContentTouches = NO;

- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view {
    if ([view isKindOfClass:[UISlider class]])
    {
        UITouch *touchEvent = [[event allTouches] anyObject];
        CGPoint locationEvent = [touchEvent locationInView:view];
        CGRect thumbRect;
        UISlider *mySlide = (UISlider*) view;
        CGRect trackRect = [mySlide trackRectForBounds:mySlide.bounds];
        thumbRect = [mySlide thumbRectForBounds:mySlide.bounds trackRect:trackRect value:mySlide.value];
        if (CGRectContainsPoint(thumbRect, locationEvent))
            return YES;
    }
    return NO;
}

Respondido 08 ago 17, 15:08

Creo que puedes obtener alguna referencia de este ejemplo en este ejemplo se muestra cómo cancelar cualquier toque o reconocimiento de gestos y aplicarlos a otras vistas.

Que esto lo lleve a la solución de su problema y si me lo hace saber

Codificación feliz :)

Respondido el 18 de junio de 12 a las 08:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.