Gérer l'événement tactile dans UILabel et le connecter à une IBAction

101

Ok, j'ai donc un UILabelconstructeur d'interface créé qui affiche un texte par défaut de "appuyez pour commencer".

Lorsque l'utilisateur appuie sur le UILabelJe veux qu'il déclenche une méthode IBAction: -(IBAction)next;qui met à jour le texte sur l'étiquette pour dire quelque chose de nouveau.
Ce serait vraiment pratique si cela me permettait simplement de faire glisser une connexion de ma méthode vers mon étiquette, puis de sélectionner retouche à l'intérieur, comme avec un bouton. mais hélas, pas de cigare.

alors de toute façon, je suppose que ma question est la suivante: est-ce que je vais devoir faire une sous-classe UILabelpour que cela fonctionne? Ou y a-t-il un moyen de faire glisser un bouton sur l'étiquette, mais de le rendre opaque à 0%. Ou y a-t-il une solution plus simple qui me manque?

wfbarksdale
la source

Réponses:

255

Vérifiez-le:

UILabel *label = ...
label.userInteractionEnabled = YES;
UITapGestureRecognizer *tapGesture =
      [[UITapGestureRecognizer alloc] initWithTarget:self 
                                              action:@selector(labelTap)];
[label addGestureRecognizer:tapGesture];

L'astuce consiste à activer l'interaction de l'utilisateur.

Scott Persinger
la source
1
Et si j'ai plusieurs étiquettes? comment pourrais-je différencier lequel a été exploité?
apprenant le
1
@learner essaie la propriété tag. assurez-vous d'utiliser labelTap: au lieu de labelTap. et utilisez - (void) labelTap: (id) sender ;.
thedjaney
1
@thedjaney L'expéditeur est le UITapGestureRecognizer, pas le UILabel
h4labs
TapGestureRecognizer n'est pas la même chose que les retouches à l'intérieur et perd la conformité et l'accessibilité de l'interface humaine.
1
@ h4labs, vous pouvez utiliser UITapGestureRecognizer * tapGesture = sender; puis récupérez l'étiquette avec tapGesture.view.tag
DJTano
70

UILabel hérite de UIView qui hérite de UIResponder. Tous les objets UIresponder peuvent gérer les événements tactiles. Donc, dans votre fichier de classe qui connaît votre vue (qui contient le UIlabel) implémentez:

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

Dans le générateur d'interface, définissez la valeur de la balise UILabel. lorsque des touches se produisent dans votre méthode touchesBegan, vérifiez la valeur de la balise de la vue à laquelle appartient la balise:

UITouch *touch = [touches anyObject];

if(touch.view.tag == MY_TAG_VAL)
label.text = @"new text";

Vous connectez votre code dans votre fichier de classe avec l'objet UILabel dans le générateur d'interface en déclarant votre variable d'instance UILabel avec le préfixe IBOutlet:

IBOutlet UILabel *label;

Ensuite, dans le constructeur d'interface, vous pouvez les connecter.

Dissolvant
la source
31
Une note, vous devez vous assurer de cocher «Interaction utilisateur activée» dans le générateur d'interface, sinon cela ne fonctionnera pas.
midas06
J'ai rencontré un problème avec cette méthode. Cela fonctionnait bien lorsque le contrôleur de vue était chargé directement, mais lorsque j'ai créé un contrôleur de navigation, poussé le contrôleur contenant l'étiquette vers le contrôleur de navigation, puis l'afficher, les touches ne semblent plus atteindre l'étiquette. Des idées?
midas06
si c'est la même classe de contrôleur de vue que vous poussez, cela devrait fonctionner. on dirait qu'il peut y avoir un autre petit problème. peut-être commencer une autre question et poster du code
Remover
5
Une méthode similaire qui ne nécessite pas d'étiquettes consiste simplement à vérifier si touch.view est égal à la prise que vous avez définie pour l'étiquette. Je préfère cela, car cela signifie que je n'ai pas à suivre les balises.
Défragmenté
excellente solution. Je vous recommande de ne définir aucune balise sur 0 car le fait de cliquer ailleurs a une valeur de balise de 0. En effet, votre vue aura très probablement une valeur de balise de 0. Sinon, vous pouvez définir la balise de votre vue sur quelque chose comme -1 et vous pouvez ensuite utiliser la valeur de la balise 0 ailleurs, c'est-à-dire un bouton
kevinl
30

Vous pouvez utiliser un UIButton, le rendre transparent, c'est-à-dire un type personnalisé sans image, et y ajouter un UILabel (centré). Ensuite, connectez les événements de bouton normaux.

Eiko
la source
Je suis d'accord, le type de bouton personnalisé devrait vous donner une expérience utilisateur de type UILabel.
stitz
2
+1, agréable et simple. J'avais déjà essayé cela en définissant un bouton normal sur opactiy 0 qui ne fonctionnait pas, mais le conseil pour changer le type en personnalisé fonctionnait parfaitement.
Brian Moeskau
L'opacité affectera le bouton et toutes ses sous-vues, donc opacity = 0 rendra le tout invisible.
Eiko
10
Yikes. C'est un hack par rapport aux autres solutions de ce fil. Utilisez un outil de reconnaissance des gestes du toucher sur une étiquette si vous souhaitez reconnaître un geste du toucher sur une étiquette. (Voyez comment cela se lit comme s'il était destiné à cela?)
James Boutcher
C'est une solution de loin, bien meilleure car les boutons gèrent les retouches à l'intérieur plutôt que de simplement tapoter (commencer).
17

Swift 3

Vous avez un IBOutlet

@IBOutlet var label: UILabel!

Dans lequel vous activez l'interaction de l'utilisateur et ajoutez un outil de reconnaissance de gestes

label.isUserInteractionEnabled = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(userDidTapLabel(tapGestureRecognizer:)))
label.addGestureRecognizer(tapGesture)

Et enfin, manipulez le robinet

func userDidTapLabel(tapGestureRecognizer: UITapGestureRecognizer) {
  // Your code goes here
}
César Cruz
la source
2
J'ai dû ajouter @objc à userDidTapLabel pour que cela fonctionne. Peut-être une chose rapide.
POSIX