Jak sprawić, by UILabel odpowiadał na dotknięcie?

94

Odkryłem, że mogę tworzyć UILabel znacznie szybciej niż UITextField i planuję używać UILabel przez większość czasu w mojej aplikacji do wyświetlania danych.

Krótko mówiąc, chciałbym pozwolić użytkownikowi dotknąć UILabel i otrzymać odpowiedź zwrotną. Czy to jest możliwe?

Dzięki.

Szczęśliwy
źródło
2
Musisz określićuserInteractionEnabled = true
onmyway133

Odpowiedzi:

210

Możesz dodać UITapGestureRecognizerinstancję do swojego UILabel.

Na przykład:

UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(labelTapped)];
tapGestureRecognizer.numberOfTapsRequired = 1;
[myLabel addGestureRecognizer:tapGestureRecognizer];
myLabel.userInteractionEnabled = YES;
pythonquick
źródło
14
Aha, właściwość „userInteractionEnabled” jest tutaj kluczowa (ponieważ inna konfiguracja może i powinna być ustawiona w scenorysach). Etykieta domyślnie wyłącza interakcję, aby przejść przez dotknięcia przez nie - ale w tym przypadku muszą obserwować dotknięcia, aby aktywować rozpoznawanie gestów. Dzięki!
Marchy
1
Niezłe! Właśnie stuknąłem w etykietę i całkowicie zapomniałem włączyć interakcję z użytkownikiem. Dzięki!
Mike Critchley
37

Jeśli używasz scenorysów, możesz wykonać cały proces w scenorysie bez dodatkowego kodu. Dodaj etykietę do serii ujęć, a następnie dodaj gest stuknięcia do etykiety. W panelu Narzędzia sprawdź, czy dla etykiety jest zaznaczona opcja „Włączono interakcję użytkownika”. Za pomocą gestu stuknięcia (na dole kontrolera widoku w scenorysie) naciśnij klawisz Ctrl + kliknij i przeciągnij do pliku ViewController.h i utwórz akcję. Następnie zaimplementuj akcję w pliku ViewController.m.

leenyburger
źródło
Metoda dostępna również przy użyciu samego
kreatora
Upewnij się, że opcja „Włączona interakcja z użytkownikiem” jest zaznaczona w sekcji Widok w Inspektorze atrybutów , a nie tylko w cechach ułatwień dostępu.
SeanR
17

Swift 3.0

Zainicjuj gest dla tempLabel

tempLabel?.text = "Label"
let tapAction = UITapGestureRecognizer(target: self, action: #selector(self.actionTapped(_:)))
tempLabel?.isUserInteractionEnabled = true
tempLabel?.addGestureRecognizer(tapAction)

Odbiornik akcji

func actionTapped(_ sender: UITapGestureRecognizer) {
    // code here
}

Swift 4.0

Zainicjuj gest dla tempLabel

tempLabel?.text = "Label"
let tapAction = UITapGestureRecognizer(target: self, action:@selector(actionTapped(_:)))
tempLabel?.isUserInteractionEnabled = true
tempLabel?.addGestureRecognizer(tapAction)

Odbiornik akcji

func actionTapped(_ sender: UITapGestureRecognizer) {
    // code here
}
Koushik
źródło
Jak uzyskać tekst etykiety z obiektu nadawcy? Innymi słowy, jak zidentyfikować nadawcę?
Vineel
Wersja Swift 4 ma @selector zamiast #selector.
Kirby Todd
8

Swift 2.0:

Dodaję ciąg nsmutable jako tekst sampleLabel, umożliwiając interakcję z użytkownikiem, dodając gest stuknięcia i wyzwalając metodę.

override func viewDidLoad() {
    super.viewDidLoad()

    let newsString: NSMutableAttributedString = NSMutableAttributedString(string: "Tap here to read the latest Football News.")
    newsString.addAttributes([NSUnderlineStyleAttributeName: NSUnderlineStyle.StyleDouble.rawValue], range: NSMakeRange(4, 4))
    sampleLabel.attributedText = newsString.copy() as? NSAttributedString

    let tapGesture: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "tapResponse:")
    tapGesture.numberOfTapsRequired = 1
    sampleLabel.userInteractionEnabled =  true
    sampleLabel.addGestureRecognizer(tapGesture)

}
func tapResponse(recognizer: UITapGestureRecognizer) {
    print("tap")
}
AG
źródło
4

Możesz zamiast tego użyć UIButton i ustawić tekst na taki, jaki chcesz. Przycisk nie musi wyglądać jak przycisk, jeśli nie chcesz

Matt S.
źródło
1
W związku z tym zawsze miałem problemy z tekstem wielowierszowym wyrównującym do lewej w UIButton. Nawet jeśli ustawię wyrównanie do lewej strony, to nadal się dzieje.
Szczęśliwego
Dałem jednak szansę UIButtonowi i jest całkiem niezły. Problem stanowią tylko przyciski wieloliniowe. Dzięki.
Szczęśliwego
3

Aby dodać gest Tap na UILable

UITapGestureRecognizer *tapAction = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(lblClick:)];
tapAction.delegate =self;
tapAction.numberOfTapsRequired = 1;

//Enable the lable UserIntraction
lblAction.userInteractionEnabled = YES;
[lblAction addGestureRecognizer:tapAction];   

oraz ocenić metodę selektora

- (void)lblClick:(UITapGestureRecognizer *)tapGesture {

}

Uwaga: Dodaj UIGestureRecognizerDelegate w pliku h

Hardik Thakkar
źródło
2

Szybka wersja: var tapGesture : UITapGestureRecognizer = UITapGestureRecognizer()

Następnie w środku viewDidLoad()dodaj to:

  let yourLbl=UILabel(frame: CGRectMake(x,y,width,height)) as UILabel!

    yourLbl.text = "SignUp"
    tapGesture.numberOfTapsRequired = 1
    yourLbl.addGestureRecognizer(tapGesture)
    yourLbl.userInteractionEnabled = true
    tapGesture.addTarget(self, action: "yourLblTapped:")
Aditya Jha
źródło
1

Jeśli chcesz użyć tekstu wielowierszowego na swoim przycisku, utwórz plik UILabel wielowierszowego tekst z tekstem wielowierszowym i dodaj jako widok podrzędny do przycisku.

na przykład:

yourLabel=[Uilabel alloc]init];
yourLabel.frame=yourButtom.Frame;//(frame size should be equal to your button's frame)
[yourButton addSubView:yourLabel]
Chandramani
źródło
1

Swift 3 od Alvina George'a

override func viewDidLoad() {
    super.viewDidLoad()
    let newsString: NSMutableAttributedString = NSMutableAttributedString(string: "Tap here to read the latest Football News.")
    newsString.addAttributes([NSUnderlineStyleAttributeName: NSUnderlineStyle.styleDouble.rawValue], range: NSMakeRange(4, 4))
    sampleLabel.attributedText = newsString.copy() as? NSAttributedString

    let tapGesture: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(ViewController.tapResponse))
    tapGesture.numberOfTapsRequired = 1
    sampleLabel.isUserInteractionEnabled =  true
    sampleLabel.addGestureRecognizer(tapGesture)
}

func tapResponse(recognizer: UITapGestureRecognizer) {
    print("tap")
}
MRustamzade
źródło
0

Wersja Swift wygląda tak:

func addGestureRecognizerLabel(){
    //Create a instance, in this case I used UITapGestureRecognizer,
    //in the docs you can see all kinds of gestures
    let gestureRecognizer = UITapGestureRecognizer()

    //Gesture configuration
    gestureRecognizer.numberOfTapsRequired = 1
    gestureRecognizer.numberOfTouchesRequired = 1
    /*Add the target (You can use UITapGestureRecognizer's init() for this)
    This method receives two arguments, a target(in this case is my ViewController) 
    and the callback, or function that you want to invoke when the user tap it view)*/
    gestureRecognizer.addTarget(self, action: "showDatePicker")

    //Add this gesture to your view, and "turn on" user interaction
    dateLabel.addGestureRecognizer(gestureRecognizer)
    dateLabel.userInteractionEnabled = true
}

//How you can see, this function is my "callback"
func showDatePicker(){
    //Your code here
    print("Hi, was clicked")
}

//To end just invoke to addGestureRecognizerLabel() when
//your viewDidLoad() method is called

override func viewDidLoad() {
    super.viewDidLoad()
    addGestureRecognizerLabel()
}
LeoGalante
źródło
0

Osobiście wolę metodę pisania rozszerzenia dla UILabel. To jest to, czego używam.

import UIKit

extension UILabel {
    /**
     * A map of actions, mapped as [ instanceIdentifier : action ].
     */
    private static var _tapHandlers = [String:(()->Void)]()

    /**
     * Retrieve the address for this UILabel as a String.
     */
    private func getAddressAsString() -> String {
        let addr = Unmanaged.passUnretained(self).toOpaque()
        return "\(addr)"
    }

    /**
     * Set the on tapped event for the label
     */
    func setOnTapped(_ handler: @escaping (()->Void)) {
        UILabel._tapHandlers[getAddressAsString()] = handler
        let gr = UITapGestureRecognizer(target: self, action: #selector(onTapped))
        gr.numberOfTapsRequired = 1
        self.addGestureRecognizer(gr)
        self.isUserInteractionEnabled = true
    }

    /**
     * Handle the tap event.
     */
    @objc private func onTapped() {
        UILabel._tapHandlers[self.getAddressAsString()]?()
    }
}

Następnie użyłbyś go w ten sposób z dowolnej instancji UILabel:

myLabel.setOnTapped {
    // do something
}

Może to potencjalnie powodować wycieki pamięci, ale nie zdecydowałem jeszcze, jak najlepiej je rozwiązać.

Nathan F.
źródło