Comment faire en sorte qu'UILabel réponde au tap?

94

J'ai découvert que je peux créer UILabel beaucoup plus rapidement que UITextField et je prévois d'utiliser UILabel la plupart du temps pour mon application d'affichage de données.

Pour faire une histoire courte cependant, je souhaite laisser l'utilisateur appuyer sur un UILabel et faire répondre mon rappel à cela. Est-ce possible?

Merci.

Heureux
la source
1
Vous devez spécifieruserInteractionEnabled = true
onmyway133

Réponses:

208

Vous pouvez ajouter une UITapGestureRecognizerinstance à votre UILabel.

Par exemple:

UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(labelTapped)];
tapGestureRecognizer.numberOfTapsRequired = 1;
[myLabel addGestureRecognizer:tapGestureRecognizer];
myLabel.userInteractionEnabled = YES;
python rapide
la source
13
Aha, la propriété 'userInteractionEnabled' ici est la clé (puisque l'autre configuration peut et doit de préférence être définie dans des storyboards). Désactivez l'interaction par défaut de l'étiquette afin de passer par les touches - mais dans ce cas, ils doivent observer les touches pour que le module de reconnaissance de gestes s'active. Merci!
Marchy
1
Joli! Je jetais juste un robinet sur une étiquette et j'ai totalement oublié d'activer l'interaction de l'utilisateur. Merci!
Mike Critchley
37

Si vous utilisez des storyboards, vous pouvez effectuer tout ce processus dans le storyboard sans code supplémentaire. Ajoutez une étiquette au storyboard, puis ajoutez un geste de toucher à l'étiquette. Dans le volet Utilitaires, assurez-vous que «Interaction utilisateur activée» est coché pour l'étiquette. À partir du geste du robinet (en bas de votre contrôleur de vue dans le storyboard), ctrl + cliquez et faites glisser vers votre fichier ViewController.h et créez une action. Ensuite, implémentez l'action dans le fichier ViewController.m.

leenyburger
la source
Méthode également disponible en utilisant le constructeur d'interface seul sans storyboards
Gomino
Assurez-vous que «Interaction utilisateur activée» est coché dans la section Affichage de l' inspecteur d' attributs , et pas seulement dans les traits d'accessibilité.
SeanR
17

Swift 3.0

Initialisez le geste pour tempLabel

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

Récepteur d'action

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

Swift 4.0

Initialisez le geste pour tempLabel

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

Récepteur d'action

func actionTapped(_ sender: UITapGestureRecognizer) {
    // code here
}
Koushik
la source
Comment obtenir le texte de l'étiquette de l'objet expéditeur? En d'autres termes, comment identifier l'expéditeur?
Vineel
La version Swift 4 a @selector au lieu de #selector.
Kirby Todd
8

Swift 2.0:

J'ajoute une chaîne nsmutable en tant que texte de sampleLabel, permettant l'interaction de l'utilisateur, ajoutant un geste de tapotement et déclenchant une méthode.

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
la source
4

Vous pouvez utiliser un UIButton à la place et définir le texte comme vous le souhaitez. Le bouton n'a pas à ressembler à un bouton si vous ne le souhaitez pas

Matt S.
la source
1
À ce sujet, j'ai toujours eu des problèmes avec le texte multiligne UIButton qui justifie à gauche. Même lorsque je règle l'alignement à gauche au centre, cela se produit toujours.
Joyeux
J'ai essayé UIButton et c'est plutôt sympa. Ce ne sont que les boutons multilignes qui posent problème. Merci.
Joyeux
3

Pour ajouter le geste Tap sur 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];   

et d'évaluer la méthode de sélection

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

}

Remarque: ajoutez UIGestureRecognizerDelegate dans le fichier .h

Hardik Thakkar
la source
2

Version Swift: var tapGesture : UITapGestureRecognizer = UITapGestureRecognizer()

Puis à l'intérieur viewDidLoad(), ajoutez ceci:

  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
la source
1

Si vous souhaitez utiliser du texte UILabelmultiligne dans votre bouton, créez un texte avec multiligne et ajoutez-le en tant que sous-vue à votre bouton.

par exemple:

yourLabel=[Uilabel alloc]init];
yourLabel.frame=yourButtom.Frame;//(frame size should be equal to your button's frame)
[yourButton addSubView:yourLabel]
Chandramani
la source
1

Swift 3 de Alvin George

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
la source
0

La version Swift ressemble à ceci:

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
la source
0

Personnellement, je préfère la méthode d'écriture d'une extension pour UILabel. C'est ce que j'utilise.

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()]?()
    }
}

Vous l'utiliseriez alors comme ceci à partir de n'importe quelle instance UILabel:

myLabel.setOnTapped {
    // do something
}

Cela peut potentiellement provoquer des fuites de mémoire, je crois, mais je n'ai pas encore déterminé la meilleure façon de les résoudre.

Nathan F.
la source