如何让 UILabel 响应点击?

我发现创建 UILabel 要比创建 UITextField 快得多,而且我计划大部分时间在我的数据显示应用程序中使用 UILabel。

不过,长话短说,我希望让用户点击 UILabel,并让我的回调响应它。这可能吗?

谢谢。

75861 次浏览

You can add a UITapGestureRecognizer instance to your UILabel.

For example:

UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(labelTapped)];
tapGestureRecognizer.numberOfTapsRequired = 1;
[myLabel addGestureRecognizer:tapGestureRecognizer];
myLabel.userInteractionEnabled = YES;

You could use a UIButton instead and set the text to what you want. The button doesn't have to look like a button if you don't want to

If you want to use Multi line text in your button then create a UILabel with Multiline text and add as a subview in to your button.

for eg:

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

If you're using storyboards you can do this entire process in the storyboard with no additional code. Add a label to the storyboard, then add a tap gesture to the label. In the Utilities pane, make sure "User Interaction Enabled" is checked for the label. From the tap gesture (at the bottom of your view controller in the storyboard), ctrl+click and drag to your ViewController.h file and create an Action. Then implement the action in the ViewController.m file.

To add Tap gesture on 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];

and to assess the selector method

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


}

Note: Add UIGestureRecognizerDelegate in .h file

Swift version looks like this:

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

Swift 2.0:

I am adding a nsmutable string as sampleLabel's text, enabling user interaction, adding a tap gesture and trigger a method.

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")
}

Swift Version: var tapGesture : UITapGestureRecognizer = UITapGestureRecognizer()

Then inside viewDidLoad(),add this:

  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:")

Swift 3 from 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")
}

Swift 3.0

Initialize the gesture for tempLabel

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

Action receiver

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

Swift 4.0

Initialize the gesture for tempLabel

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

Action receiver

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

I personally prefer the method of writing an extension for UILabel. This is what I use.

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

You would then use it like this from any UILabel instance:

myLabel.setOnTapped {
// do something
}

This can potentially cause some memory leaks I believe, but I haven't determined how best to resolve them yet.

This works great in Xcode 12 and Swift 5

let tapAction = UITapGestureRecognizer(target: self,action:#selector(actionTapped(_:)))


userLabel?.isUserInteractionEnabled = true


userLabel?.addGestureRecognizer(tapAction)

And action method like -

@objc func actionTapped(_ sender: UITapGestureRecognizer) {
print("tapped")
}