Gestire l'evento Touch in UILabel e collegarlo a un'IBAction


101

Ok, quindi ho UILabelcreato un generatore di interfacce che mostra del testo predefinito di "tocca per iniziare".

Quando l'utente tocca il UILabelpulsante Voglio che attivi un metodo IBAction: -(IBAction)next;che aggiorna il testo sull'etichetta per dire qualcosa di nuovo.
Sarebbe davvero conveniente se questo mi permettesse di trascinare semplicemente una connessione dal mio metodo alla mia etichetta e quindi selezionare il ritocco all'interno, come con un pulsante. ma ahimè, niente sigaro.

quindi, comunque, immagino che la mia domanda sia: dovrò creare una sottoclasse UILabelper farlo funzionare? O c'è un modo per trascinare un pulsante sull'etichetta, ma renderlo opaco allo 0%. O c'è una soluzione più semplice che mi manca?

Risposte:


255

Controlla:

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

Il trucco sta nell'abilitare l'interazione dell'utente.


1
E se ho più etichette? come potrei differenziare quale è stato sfruttato?
studente

1
@learner prova la proprietà tag. assicurati di usare labelTap: invece di labelTap. e usa - (void) labelTap: (id) sender ;.
thedjaney

1
@thedjaney Il mittente è l'UITapGestureRecognizer, non l'UILabel
h4labs

TapGestureRecognizer non è la stessa cosa del ritocco all'interno e perde la conformità e l'accessibilità dell'interfaccia umana.

1
@ h4labs puoi usare UITapGestureRecognizer * tapGesture = sender; quindi ottieni il tag dell'etichetta con tapGesture.view.tag
DJTano

70

UILabel eredita da UIView che eredita da UIResponder. Tutti gli oggetti UIresponder possono gestire eventi di tocco. Quindi nel tuo file di classe che conosce la tua vista (che contiene l'UIlabel) implementa:

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

In Interface Builder impostare il valore del tag UILabel. quando si verificano dei tocchi nel metodo touchesBegan, controlla il valore del tag della vista a cui appartiene il tag:

UITouch *touch = [touches anyObject];

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

Connetti il ​​tuo codice nel tuo file di classe con l'oggetto UILabel nel generatore di interfacce dichiarando la tua variabile di istanza UILabel con il prefisso IBOutlet:

IBOutlet UILabel *label;

Quindi nel generatore di interfacce puoi collegarli.


31
Una nota, devi assicurarti di selezionare "Interazione utente abilitata" nel generatore di interfacce, altrimenti non funzionerà.
midas06

Ho riscontrato un problema con questo metodo. Ha funzionato bene quando il controller di visualizzazione è stato caricato direttamente, ma quando ho creato un controller di navigazione, ho spinto il controller contenente l'etichetta nel controller di navigazione e quindi visualizzandolo, i tocchi non sembrano più arrivare all'etichetta. Qualche idea?
midas06

se è la stessa classe del controller di visualizzazione che stai spingendo dovrebbe funzionare. sembra che ci possa essere qualche altro piccolo problema. forse inizia un'altra domanda e pubblica un codice
Remover

5
Un metodo simile che non richiede tag è semplicemente controllare se touch.view è uguale alla presa che hai impostato per l'etichetta. Lo preferisco, perché significa che non devo tenere traccia dei tag.
Deframmentato

ottima soluzione. Ti consiglio di non impostare alcun tag su 0 perché fare clic in un altro posto ha un valore di tag 0. Questo perché la tua vista molto probabilmente avrà un valore di tag di 0. Altrimenti, puoi impostare il tag della tua vista su qualcosa come -1 e poi puoi usare il valore del tag 0 da qualche altra parte, ad esempio un pulsante
kevinl

30

Puoi usare un UIButton, renderlo trasparente, cioè un tipo personalizzato senza un'immagine, e aggiungere un'etichetta UIL su di esso (centrato). Quindi collegare i normali eventi dei pulsanti.


Sono d'accordo, il tipo di pulsante personalizzato dovrebbe darti un'esperienza utente di tipo UILabel.
stitz

2
+1, bello e semplice. Avevo provato prima impostando un normale pulsante su opactiy 0 che non funzionava, ma il suggerimento per cambiare il tipo in personalizzato ha funzionato perfettamente.
Brian Moeskau

L'opacità avrà effetto sul pulsante e su tutte le sue sottoview, quindi opacity = 0 renderà l'intera cosa invisibile.
Eiko

10
Yikes. Questo è un trucco rispetto alle altre soluzioni in questo thread. Utilizza un riconoscimento del gesto del tocco su un'etichetta se desideri riconoscere un gesto del tocco su un'etichetta. (Vedi come si legge come se fosse pensato per questo?)
James Boutcher

Questa è una soluzione di gran lunga migliore perché i pulsanti gestiscono il tocco all'interno piuttosto che solo i tocchi (inizio).

17

Swift 3

Hai un IBOutlet

@IBOutlet var label: UILabel!

In cui abiliti l'interazione dell'utente e aggiungi un riconoscimento dei gesti

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

E infine, gestisci il rubinetto

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

2
Ho dovuto aggiungere @objc a userDidTapLabel per farlo funzionare. Potrebbe essere una cosa rapida 4.
Conformità POSIX
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.