2010-06-03 15 views
7

Tengo un problema con los botones y las animaciones. Básicamente, estoy animando una vista usando las animaciones de UIView mientras trato de escuchar los toques en el botón dentro de la vista. La vista es tan grande como el botón, y la vista es en realidad una subclase de UIImageView con una imagen debajo del botón. La vista es una subvista de una vista de contenedor ubicada en el Interface Builder con la interacción del usuario habilitada y la opción de clipping habilitada. Toda la animación y el manejo de los botones se realiza en esta subclase UIImageView, mientras que el mensaje startFloating se envía desde una clase separada según sea necesario.Animación de iPhone UIView Desactiva la subvista UIButton

Si no hago ninguna animación, el mensaje buttonTapped: se envía correctamente, pero durante la animación no se envía. También intenté implementar el método touchesEnded, y ocurre el mismo comportamiento.

UIImageView init subclase (tengo el botón rellenar con un color para que pueda ver el fotograma obtiene configurar correctamente, lo que lo hace):

- (id)initWithImage:(UIImage *)image { 
    self = [super initWithImage:image]; 
    if (self != nil) { 
     // ...stuffs 

     UIButton *tapBtn = [UIButton buttonWithType:UIButtonTypeCustom]; 
     tapBtn.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height); 
     [tapBtn addTarget:self action:@selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside]; 
     tapBtn.backgroundColor = [UIColor cyanColor]; 
     [self addSubview:tapBtn]; 

     self.userInteractionEnabled = YES; 
    } 
    return self; 
} 
método

animación que inicia la animación (si no lo hago llaman a esto el botón funcionará correctamente):

- (void)startFloating { 
    [UIView beginAnimations:@"floating" context:nil]; 
    [UIView setAnimationDelegate:self]; 
    [UIView setAnimationCurve:UIViewAnimationCurveLinear]; 
    [UIView setAnimationDuration:10.0f]; 
    self.frame = CGRectMake(self.frame.origin.x, -self.frame.size.height, self.frame.size.width, self.frame.size.height); 
    [UIView commitAnimations]; 
} 

Por lo tanto, para ser claros:

  • el uso de la animación UIView efectivamente desactiva el botón.
  • Al desactivar la animación, el botón funciona.
  • El botón tiene el tamaño y posición correctos en la pantalla, y se mueve junto con la vista correctamente.

Respuesta

7

La animación es solo ojos dulces. La animación se retrasa detrás del movimiento real de la vista. El botón ya está en el punto de destino cuando comienza la animación. Usted acaba de ver una película de la vista/botón en movimiento.

Si desea que se pueda hacer clic en un botón durante la animación, tendrá que hacer la animación usted mismo.

+0

Hmm después de hacer algunas pruebas yo creo que son correctos. Sin embargo, esto parece bastante jodido, en contra de las expectativas de animación. Cuando dices "haz la animación tú mismo", ¿te refieres a una animación de estilo NSTimer? También supongo que la implementación de la familia de métodos toques exhibiría el mismo comportamiento? – bensnider

+0

Así que sí, usando una animación NSTimer puedo usar el botón de esta manera. Gracias. – bensnider

+0

También podría hacer el seguimiento táctil usted mismo y no depender en absoluto del botón. Todavía requeriría alguna animación manual, pero puede brindarle mejores resultados para la interacción. – axiixc

5

... estaba experimentando el mismo problema porque mi código estaba haciendo una gran animación por bloque. Hice una solución basada en NSTimer, como la sugerida anteriormente, y funcionó ... sin embargo, el movimiento fue desigual (a menos que insertara una animación dentro de cada activador de evento de temporizador).

Por lo tanto, como se requería animación de todos modos, encontré una solución que no requiere temporizador. Anime solo una corta distancia y, por lo tanto, el clic del botón sigue siendo preciso, con solo un pequeño error que es mi caso es muy imperceptible en la interfaz de usuario, y puede reducirse dependiendo de tus parámetros.

Tenga en cuenta que el error en cualquier momento dado es < 15.0, que se puede reducir para obtener una mayor precisión, según los requisitos de velocidad de su animación. También puede reducir el tiempo de duración para obtener más velocidad.

- (void)conveyComplete:(UIView*)v 
{ 
    [self convey:v delay:0]; 
} 

- (void)convey:(UIView*)v delay:(int)nDelay 
{ 
    [UIView animateWithDuration:.5 
          delay:nDelay 
         options:(UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction) 
        animations:^
        { 
         CGRect rPos = v.frame; 
         rPos.origin.x -= 15.0; 
         v.frame = rPos; 
        } 
        completion: ^(BOOL finished) 
        { 
         [self conveyComplete:v]; 
        }]; 

} 
20

esto resuelve el problema:

[UIView animateWithDuration:20 delay: 0.0 options: UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction 
    ... 
+1

'UIViewAnimationOptionAllowUserInteraction' es lo que necesitaba. ¡Gracias! – buildsucceeded