Behandeln von Touch-Ereignissen in UILabel und Anschließen an eine IBAction


101

Ok, ich habe einen UILabelim Interface Builder erstellten Standardtext "Tap to begin" angezeigt.

Wenn der Benutzer auf tippt UILabel, soll eine IBAction-Methode ausgelöst werden, -(IBAction)next;die den Text auf dem Etikett aktualisiert, um etwas Neues zu sagen.
Es wäre sehr praktisch, wenn ich auf diese Weise einfach eine Verbindung von meiner Methode auf mein Etikett ziehen und dann wie mit einer Schaltfläche die Option "Nachbessern" auswählen könnte. aber leider keine Zigarre.

Wie auch immer, ich denke meine Frage ist, muss ich eine Unterklasse bilden UILabel, damit dies funktioniert? Oder gibt es eine Möglichkeit, eine Schaltfläche über das Etikett zu ziehen, sie jedoch zu 0% undurchsichtig zu machen? Oder gibt es eine einfachere Lösung, die mir fehlt?

Antworten:


255

Hör zu:

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

Der Trick besteht darin, die Benutzerinteraktion zu aktivieren.


1
Was ist, wenn ich mehrere Etiketten habe? Wie kann ich unterscheiden, welches angetippt wurde?
Lerner

1
@Learner versuchen Sie die Tag-Eigenschaft. Stellen Sie sicher, dass Sie labelTap: anstelle von labelTap verwenden. und benutze - (void) labelTap: (id) sender;.
Thedjaney

1
@thedjaney Der Absender ist der UITapGestureRecognizer, nicht der UILabel
h4labs

TapGestureRecognizer ist nicht dasselbe wie das Ausbessern im Inneren und verliert die Konformität und Zugänglichkeit der Benutzeroberfläche.

1
@ h4labs können Sie UITapGestureRecognizer verwenden * tapGesture = sender; Dann holen Sie sich das Label-Tag mit tapGesture.view.tag
DJTano

70

UILabel erbt von UIView, das von UIResponder erbt. Alle UIresponder-Objekte können Berührungsereignisse verarbeiten. Implementieren Sie also in Ihrer Klassendatei, die über Ihre Ansicht Bescheid weiß (die das UIlabel enthält):

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

Legen Sie im Interface Builder den Tag-Wert des UILabels fest. Wenn in Ihrer touchBegan-Methode Berührungen auftreten, überprüfen Sie den Tag-Wert der Ansicht, zu der das Tag gehört:

UITouch *touch = [touches anyObject];

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

Sie verbinden Ihren Code in Ihrer Klassendatei mit dem UILabel-Objekt im Interface Builder, indem Sie Ihre UILabel-Instanzvariable mit dem IBOutlet-Präfix deklarieren:

IBOutlet UILabel *label;

Dann können Sie sie im Interface Builder verbinden.


31
Ein Hinweis: Sie müssen sicherstellen, dass Sie im Benutzeroberflächen-Generator "Benutzerinteraktion aktiviert" aktivieren. Andernfalls funktioniert dies nicht.
Midas06

Ich habe ein Problem mit dieser Methode getroffen. Es hat gut funktioniert, als der View-Controller direkt geladen wurde, aber als ich einen Navi-Controller erstellt, den Controller mit dem Etikett auf den Navi-Controller verschoben und dann angezeigt habe, scheinen die Berührungen nicht mehr auf das Etikett zu gelangen. Irgendwelche Ideen?
Midas06

Wenn es sich um dieselbe View Controller-Klasse handelt, die Sie pushen, sollte dies funktionieren. klingt so, als ob es ein anderes kleines Problem geben könnte. Vielleicht starten Sie eine andere Frage und posten Sie einen Code
Remover

5
Eine ähnliche Methode, für die keine Tags erforderlich sind, besteht darin, einfach zu überprüfen, ob touch.view dem für das Etikett festgelegten Ausgang entspricht. Ich bevorzuge dies, da ich die Tags nicht im Auge behalten muss.
Defragmentiert

tolle Lösung. Ich empfehle, dass Sie kein Tag auf 0 setzen, da das Klicken auf eine andere Stelle einen Tag-Wert von 0 hat. Dies liegt daran, dass Ihre Ansicht höchstwahrscheinlich einen Tag-Wert von 0 hat. Andernfalls können Sie das Tag Ihrer Ansicht auf setzen so etwas wie -1 und dann können Sie den Tag-Wert von 0 woanders verwenden, dh eine Schaltfläche
Kevin

30

Sie können einen UIButton verwenden, ihn transparent machen, dh einen benutzerdefinierten Typ ohne Bild, und ein UILabel hinzufügen (zentriert). Verdrahten Sie dann die normalen Tastenereignisse.


Ich bin damit einverstanden, dass der benutzerdefinierte Schaltflächentyp eine Benutzererfahrung vom Typ UILabel bietet.
stitz

2
+1, nett und einfach. Ich hatte dies zuvor versucht, indem ich eine normale Schaltfläche auf opactiy 0 gesetzt hatte, was nicht funktionierte, aber der Tipp, den Typ in benutzerdefiniert zu ändern, funktionierte perfekt.
Brian Moeskau

Die Deckkraft wirkt sich auf die Schaltfläche und alle ihre Unteransichten aus, sodass Deckkraft = 0 das Ganze unsichtbar macht.
Eiko

10
Huch. Dies ist ein Hack im Vergleich zu den anderen Lösungen in diesem Thread. Verwenden Sie eine Tippgestenerkennung auf einem Etikett, wenn Sie eine Tippgeste auf einem Etikett erkennen möchten. (Sehen Sie, wie es liest, als wäre es dafür gedacht?)
James Boutcher

Dies ist eine weitaus bessere Lösung, da Tasten Touchupinside handhaben und nicht nur tippen (beginnen).

17

Swift 3

Sie haben ein IBOutlet

@IBOutlet var label: UILabel!

In dem Sie die Benutzerinteraktion aktivieren und einen Gestenerkenner hinzufügen

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

Und zum Schluss den Wasserhahn anfassen

func userDidTapLabel(tapGestureRecognizer: UITapGestureRecognizer) {
  // Your code goes here
}

2
Ich musste @objc zu userDidTapLabel hinzufügen, damit dies funktioniert. Könnte eine schnelle Sache sein.
POSIX-konform
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.