2010-06-03 8 views
7

J'ai donc un problème avec les boutons et les animations. Fondamentalement, j'anime une vue en utilisant les animations UIView tout en essayant d'écouter les taps sur le bouton à l'intérieur de la vue. La vue est aussi grande que le bouton, et la vue est en réalité une sous-classe de UIImageView avec une image sous le bouton. La vue est une sous-vue d'une vue de conteneur placée dans Interface Builder avec l'interaction de l'utilisateur activée et l'écrêtage activé. Toutes les animations et manipulations de boutons sont effectuées dans cette sous-classe UIImageView, tandis que le message startFloating est envoyé depuis une classe séparée si nécessaire.iPhone UIView Animation désactive UIButton Subview

Si je ne fais pas d'animation, le message buttonTapped: est envoyé correctement, mais pendant l'animation, il n'est pas envoyé. J'ai également essayé d'implémenter la méthode touchesEnded, et le même comportement se produit.

UIImageView sous-classe init (j'ai le bouton rempli d'une couleur que je peux voir le cadre se prépare correctement, ce qu'il fait):

- (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éthode

d'animation qui démarre l'animation (si je ne le fais pas appellent cela le bouton fonctionne correctement):

- (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]; 
} 

donc, pour être clair:

  • Utilisation de l'animation UIView désactive efficacement le bouton.
  • La désactivation de l'animation provoque le fonctionnement du bouton.
  • Le bouton est correctement dimensionné et positionné sur l'écran et se déplace correctement avec la vue.

Répondre

7

L'animation est juste eye candy. L'animation est en retard sur le mouvement réel de la vue. Le bouton est déjà au point de destination lorsque l'animation démarre. Vous venez de voir un film de la vue/bouton en mouvement.

Si vous voulez qu'un bouton soit cliquable pendant l'animation, vous devrez faire l'animation vous-même.

+0

Hmm après avoir fait quelques tests, je ne crois que vous avez raison. Cela semble assez janky cependant, contre les attentes pour l'animation. Quand vous dites "faites l'animation vous-même" vous faites référence à une animation de style NSTimer? Aussi je suppose que la mise en œuvre de la famille des méthodes toucherait le même comportement? – bensnider

+0

Donc oui en utilisant une animation NSTimer je suis capable d'utiliser le bouton de cette manière. Merci. – bensnider

+0

Vous pouvez également faire vous-même le suivi du contact et ne pas compter sur le bouton du tout. Cela nécessiterait encore une animation manuelle, mais pourrait vous donner de meilleurs résultats pour l'interaction. – axiixc

5

... rencontrait ce même problème car mon code faisait une grande animation par bloc. J'ai fait une solution basée sur NSTimer, comme celle suggérée ci-dessus, et cela a fonctionné ... mais le mouvement était saccadé (à moins que j'insère de l'animation dans chaque déclencheur d'événement de minuterie). Donc, comme l'animation était nécessaire de toute façon, j'ai trouvé une solution qui ne nécessite aucune minuterie. Il n'anime que sur une courte distance et donc le clic du bouton est toujours précis, avec seulement une petite erreur qui est mon cas est très imperceptible dans l'interface utilisateur, et peut être réduite en fonction de vos paramètres.

Notez ci-dessous que l'erreur à un moment donné est < 15,0, ce qui peut être réduit pour plus de précision en fonction de vos exigences de vitesse d'animation. Vous pouvez également réduire la durée pour plus de vitesse.

- (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

cela résout le problème:

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

'UIViewAnimationOptionAllowUserInteraction' est ce dont j'avais besoin. Merci! – buildsucceeded