Problème de touch sur un élément en mouvement

apocaalypsoapocaalypso Membre
00:30 modifié dans API UIKit #1
Bonjour,

J'ai plusieurs UILabel que je fais bouger avec UIView beginAnimation: en changeant leur coordonnées de centre :
[UIView beginAnimations:nil context:self];<br />	[UIView setAnimationCurve:UIViewAnimationCurveLinear];<br />	[UIView setAnimationDuration:7];<br />	[UIView setAnimationDelay:7];<br />	label.center = CGPointMake(x, y);<br />	[UIView commitAnimations];<br />


Dans ma méthode de détection de touch, je souhaite, lorsque l'utilisateur touche un UIlabel en particulier le détecter. Mais ceci ne marche que lorsque le label n'est pas encore en mouvement, voici mon code pour détecter le label :

for(UILabel *label in self.subviews)<br />	{<br />		if([label isKindOfClass:[UILabel class]] &amp;&amp; CGRectContainsPoint(label.frame, location))<br />		{<br />			NSLog(@&quot;Touched = %@&quot;, label.text);<br />			break;<br />		}<br />	}


Je ne comprend pas pourquoi ça ne marche pas, peut-être que la frame du label n'est pas mis à  jour avec les nouvelles coordonnées ?

Merci d'avance !

Réponses

  • AliGatorAliGator Membre, Modérateur
    00:30 modifié #2
    La frame du label correspond à  la valeur dans le Layer Tree et non dans le PresentationTree je pense.

    Pourquoi ne pas utiliser les méthodes containsPoint et hitTest de UIView (dont dérive UILabel) ? D'autant que le problème de CGRectContainsPoint et des frames c'est que comme leur nom l'indique ce sont de Rect et des frames, donc rectangulaires et surtout parallèles à  l'écran... or comme ton animation peut contenir des rotations de ton UILabel (même si ce n'est pas le cas ici, mais de manière générale et conceptuelle), bah dans ce genre de cas la frame n'est plus valide, et il me parait pas la meilleure des idées que de se baser dessus dans ce genre de cas.
  • apocaalypsoapocaalypso Membre
    00:30 modifié #3
    Ce n'est pas déjà  un containsPoint que j'utilise ?
  • AliGatorAliGator Membre, Modérateur
    00:30 modifié #4
    Je voulais parler de [tt]- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event[/tt] de la classe UIView. C'est comme ça qu'on teste pour savoir quelle subview d'une vue est touchée en général quand on veut faire ça "manuellement" (avec les subviews ayant leur touchInteractionEnabled à  NO pour que ce soit la superview qui gère ses subviews ainsi et non pas chaque subview qui se gère indépendemment)
  • apocaalypsoapocaalypso Membre
    00:30 modifié #5
    Merci Ali pour ces explications, j'ai rajouté ce que tu m'as dit mais ça n'a pas l'air de marcher, voici les changements :

    for(UILabel *label in self.subviews)<br />	{<br />		if([label isKindOfClass:[UILabel class]] &amp;&amp; [label pointInside:location withEvent:event])<br />		{<br />			NSLog(@&quot;Touched = %@&quot;, label.text);<br />			break;<br />		}<br />	}
    
  • Philippe49Philippe49 Membre
    00:30 modifié #6
    Dans CountItRight, j'ai des boutons qui se déplacent sur l'interface, et qui peuvent revenir à  leur place initiale. J'ai mis en place le mécanisme ainsi, et (après les tests dévastateurs de mon fils !) c'est robuste

    [chip addTarget:self action:@selector(installChipInLine:) forControlEvents:UIControlEventTouchDown];<br />	[chip addTarget:self action:@selector(resetPositionOfChip:) forControlEvents:UIControlEventTouchDragOutside];
    

    Chaque méthode (selector) lance une nouvelle animation.
  • apocaalypsoapocaalypso Membre
    00:30 modifié #7
    Merci Philippe, j'ai pas pensé à  ça !
    Mais par contre, comment pourrais-je faire pour faire passer des arguments à  la méthode cible ?
  • Philippe49Philippe49 Membre
    00:30 modifié #8
    La doc de UIControl

    UIKit allows three different forms of action selector:
    - (void)action
    - (void)action:(id)sender
    - (void)action:(id)sender forEvent:(UIEvent *)event

    On peut donc récupérer l'event et le sender. On peut lire les données de ton UILabel, et si tu en as plusieurs le personnaliser en renseignant sa property tag.
     
  • apocaalypsoapocaalypso Membre
    00:30 modifié #9
    Merci Philippe, j'ai fait ça avec tag, donc j'ai converti mes UILabel en UIButton.

    Mais le problème qui demeure c'est que l'action associée à  mon bouton ne se déclenche pas lorsque celui-ci est en mouvement.
Connectez-vous ou Inscrivez-vous pour répondre.