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?

wfbarksdale
quelle

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.

Scott Persinger
quelle
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.

Entferner
quelle
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.

Eiko
quelle
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
}
César Cruz
quelle
2
Ich musste @objc zu userDidTapLabel hinzufügen, damit dies funktioniert. Könnte eine schnelle Sache sein.
POSIX-konform