eventos de toque UIScrollView durante la animación no disparar con animateWithDuration: pero funcionan bien con UIView beginAnimations:

StackOverflow https://stackoverflow.com/questions/3614116

Pregunta

Tengo una subclase UIScrollView que estoy usando animaciones mediante programación Desplazamiento UIView.

Me gustaría que el usuario sea capaz de girar o hacer zoom en el contenido UIImageView del Rollo Ver mientras la animación está teniendo lugar.

Esto tiene funcionaba bien durante el uso de una formulación similar a la siguiente:

- (void) scrollSmoothlyatPixelsPerSecond:(float)thePixelsPerSecond {
    // distance in pixels / speed in pixels per second
    float animationDuration = _scrollView.contentSize.width / thePixelsPerSecond;

    [UIView beginAnimations:@"scrollAnimation" context:nil];
    [UIView setAnimationCurve: UIViewAnimationCurveLinear];
    [UIView setAnimationDuration:animationDuration];
    _scrollView.contentOffset = CGPointMake(_scrollView.contentSize.width, 0);
    [UIView commitAnimations];
}

Ahora, ya que iOS 4.0, UIView beginAnimations: no se recomienda. Así que traté de actualizar mi código utilizando un bloque y UIView animateWithDuration: El desplazamiento funciona de forma idéntica a la anterior.

La clave y la diferencia enloquecedor es que durante la animación, el UIScrollView y otros puntos de vista que ya no responden a los métodos de control de eventos:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; 

Ni tampoco:

-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView;

get llama cuando se trata de hacer zoom.

Editar para mayor claridad: No UIView presentes responde al tacto eventos. Esto no se limita sólo a la UIScrollView. pares del UIScrollView un UIToolbar no responde a eventos de toque, ni otros botones que son subvistas de un par a la UIScrollView. Parece que todo el UIView matriz está congelada fuera de la interacción del usuario , mientras que la animación está pasando . Una vez más, después de que se complete la animación, todas las UIViews anteriores son más sensibles.

todos estos hacen ser llamado en los beginAnimations UIView:. Formulación independientemente del estado de la animación

Mi animateWithDuration: código es ligeramente diferente - pero las diferencias no son significativas. Tan pronto como se complete la animación, los eventos táctiles anteriores son llamados de nuevo ...

aquí está mi código animado:

- (void) scrollSmoothlyToSyncPoint:(SyncPoint *) theSyncPoint andContinue:(BOOL)theContinueFlag{

    float animationDuration = theSyncPoint.time - [player currentTime];
    [UIView animateWithDuration:animationDuration 
                          delay:0 
                        options:UIViewAnimationOptionCurveLinear 
                     animations:^{
        [_scrollView setContentOffset:theSyncPoint.contentOffset];
    } 
                     completion:^(BOOL finished){
                         if (theContinueFlag) {
                             SyncPoint *aSyncPoint = [self nextSyncPoint];
                             if (aSyncPoint) {
                                 [self scrollSmoothlyToSyncPoint:aSyncPoint andContinue:YES];
                             }
                         }
    }];
}

El único controlador de eventos que se activa durante el bloque de animación de arriba es:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;

Por lo tanto, la pregunta: ¿Debo - Ignorar desalentado etiqueta de Apple y seguir utilizando la formulación BeginAnimation? ¿Debo - mis otros eventos táctiles zoom reimplementar y el uso de hitTest? ¿Hay algún conocimiento de la diferencia de aplicación entre los bloques de animación que me puedan ayudar a hacer frente a este problema? ¿Hay algo obvio que me falta?

Soy un nuevo desarrollador de Apple, y por lo tanto no sé qué tan seriamente a tomar su etiqueta desalentado . Pero si esta API dejará de estar disponible luego desaparecen, prefiero moverse en una dirección duradera.

Muchas gracias por su atención.

¿Fue útil?

Solución

Sólo tiene que incluir la opción UIViewAnimationOptionAllowUserInteraction al invocar la animación de esta manera:

[UIView animateWithDuration:animationDuration 
                          delay:0 
                        options:(UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction)
                     <snip>];

Esa es una disimulada, lo sé! ;)

Re: La etiqueta "desalentados" - En general, cuando Apple dice que no haga algo en lo que se refiere al diseño de aplicaciones que se ejecutan en sus plataformas, por lo general es para su propio bien. Así que usted tiene razón en querer adoptar bloques de animación en lugar de la vieja manera torpe.

Otros consejos

respuesta

de quickthyme es correcta. Aquí está el fragmento en Swift

Swift 4

UIView.animate(
    withDuration: 0.3, // specify animation duration here 
    delay: 0, // specify delay if needed 
    options: [
        UIView.AnimationOptions.allowUserInteraction, 
        UIView.AnimationOptions.curveLinear
    ], 
    animations: {
        // animations code    
    }
)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top