Obsługa zdarzenia dotykowego w UILabel i podłączanie go do IBAction

101

Ok, mam więc UILabelutworzony w interfejsie kreator, który wyświetla jakiś domyślny tekst „dotknij, aby rozpocząć”.

Gdy użytkownik naciśnie przycisk UILabelChcę, aby wyzwolił metodę IBAction: -(IBAction)next;która aktualizuje tekst na etykiecie, aby powiedzieć coś nowego.
Byłoby naprawdę wygodne, gdyby to pozwoliło mi po prostu przeciągnąć połączenie z mojej metody na etykietę, a następnie wybrać retusz wewnątrz, tak jak w przypadku przycisku. ale niestety nie ma cygara.

więc w każdym razie, myślę, że moje pytanie brzmi: czy będę musiał przejść podklasę, UILabelaby to zadziałało? Czy jest jakiś sposób, żebym mógł przeciągnąć przycisk nad etykietą, ale uczynić go nieprzezroczystym w 0%. Czy może brakuje mi prostszego rozwiązania?

wfbarksdale
źródło

Odpowiedzi:

255

Sprawdź to:

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

Sztuczka polega na umożliwieniu interakcji użytkownika.

Scott Persinger
źródło
1
A jeśli mam wiele etykiet? jak mogę rozróżnić, który z nich został dotknięty?
uczeń
1
@learner wypróbuj właściwość tagu. upewnij się, że używasz labelTap: zamiast labelTap. i użyj - (void) labelTap: (id) sender ;.
thedjaney
1
@thedjaney Nadawcą jest UITapGestureRecognizer, a nie UILabel
h4labs
TapGestureRecognizer to nie to samo, co retusz wewnątrz i traci zgodność i dostępność interfejsu ludzkiego.
1
@ h4labs możesz użyć UITapGestureRecognizer * tapGesture = sender; następnie pobierz tag etykiety z tapGesture.view.tag
DJTano
70

UILabel dziedziczy po UIView, który dziedziczy po UIResponder. Wszystkie obiekty UIresponder mogą obsługiwać zdarzenia dotykowe. Więc w pliku klasy, który wie o twoim widoku (który zawiera UIlabel) zaimplementuj:

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

W programie do tworzenia interfejsów ustaw wartość tagu UILabel. kiedy dotknięcia występują w metodzie touchesBegan, sprawdź wartość tagu widoku, do którego należy tag:

UITouch *touch = [touches anyObject];

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

Łączysz swój kod w pliku klasy z obiektem UILabel w programie do tworzenia interfejsów, deklarując zmienną instancji UILabel z prefiksem IBOutlet:

IBOutlet UILabel *label;

Następnie w kreatorze interfejsów możesz je połączyć.

Zmywacz
źródło
31
Jedna uwaga, musisz upewnić się, że zaznaczyłeś „Włączono interakcję z użytkownikiem” w narzędziu do tworzenia interfejsu, inaczej to nie zadziała.
midas06
Tą metodą napotkałem jeden problem. Działało dobrze, gdy kontroler widoku był ładowany bezpośrednio, ale kiedy utworzyłem kontroler nawigacyjny, pchnąłem kontroler zawierający etykietę do kontrolera nawigacyjnego, a następnie go wyświetliłem, dotknięcia wydają się już nie docierać do etykiety. Jakieś pomysły?
midas06
jeśli jest to ta sama klasa kontrolera widoku, którą pchasz, powinna działać. wygląda na to, że może być jakiś inny mały problem. może zacznij inne pytanie i napisz jakiś kod
Remover
5
Podobną metodą, która nie wymaga tagów, jest po prostu sprawdzenie, czy touch.view jest równy gniazdu ustawionemu dla etykiety. Wolę to, ponieważ oznacza to, że nie muszę śledzić tagów.
Zdefragmentowano
świetne rozwiązanie. Zalecam, aby nie ustawiać żadnego tagu na 0, ponieważ kliknięcie w innym miejscu ma wartość tagu 0. Dzieje się tak, ponieważ Twój widok najprawdopodobniej będzie miał wartość tagu 0. W przeciwnym razie możesz ustawić tag swojego widoku na coś takiego jak -1 i wtedy możesz użyć wartości tagu 0 gdzieś indziej, np. przycisku
kevinl
30

Możesz użyć UIButton, uczynić go przezroczystym, tj. Niestandardowy typ bez obrazu i dodać do niego UILabel (wyśrodkowany). Następnie połącz normalne zdarzenia przycisków.

Eiko
źródło
Zgadzam się, niestandardowy typ przycisku powinien zapewniać wygodę użytkowania typu UILabel.
stitz
2
+1, ładne i proste. Próbowałem tego wcześniej, ustawiając normalny przycisk na opactiy 0, co nie działało, ale wskazówka dotycząca zmiany typu na niestandardowy działała idealnie.
Brian Moeskau
Przezroczystość wpłynie na przycisk i wszystkie jego podglądy, więc krycie = 0 sprawi, że całość będzie niewidoczna.
Eiko
10
Yikes. To hack w porównaniu do innych rozwiązań w tym wątku. Użyj rozpoznawania gestów dotknięcia na etykiecie, jeśli chcesz rozpoznać gest dotknięcia na etykiecie. (Zobacz, jak to brzmi, jakby było to przeznaczone?)
James Boutcher
Jest to o wiele lepsze rozwiązanie, ponieważ przyciski obsługują dotyk wewnątrz, a nie tylko dotknięcia (początek).
17

Szybki 3

Masz IBOutlet

@IBOutlet var label: UILabel!

W którym włączasz interakcję z użytkownikiem i dodajesz rozpoznawanie gestów

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

I na koniec obsłuż kran

func userDidTapLabel(tapGestureRecognizer: UITapGestureRecognizer) {
  // Your code goes here
}
César Cruz
źródło
2
Musiałem dodać @objc do userDidTapLabel, aby to zadziałało. To może być szybka 4 rzecz.
Zgodny z POSIX