如何使一个UILabel可点击?

173

我想让一个UILabel可点击。

我已经尝试过这个方法,但是它没有起作用:

class DetailViewController: UIViewController {

    @IBOutlet weak var tripDetails: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        ...
        let tap = UITapGestureRecognizer(target: self, action: Selector("tapFunction:"))
        tripDetails.addGestureRecognizer(tap)
    }

    func tapFunction(sender:UITapGestureRecognizer) {
        print("tap working")
    }
}

4
你的UILabel的框架是什么?你确定你正在触摸标签的框架内吗?有没有其他UIViews遮盖住标签?标签的userInteractionEnabled属性设置为True了吗? - JAL
请确保您的 UILabel IBOutlet 已从 Nib 或 Storyboard 连接。 - aahrens
12个回答

209

您尝试将isUserInteractionEnabled设置为truetripDetails标签上吗?这应该可以解决问题。


1
谢谢你的回答!!!这里我还有一个关于UITapGestureRecognizer的问题:https://dev59.com/z1wX5IYBdhLWcg3wjwJZ - Daniele B
我正在尝试在点击时更改背景颜色,但是触摸事件在我松开手指时才触发。有没有办法捕获按下事件?长按不是我要找的。 - Numan Karaaslan
哦,哇,所以标签默认情况下不可交互,感谢! - Dan

131

Swift 3 更新

替换

Selector("tapFunction:")

带有

#selector(DetailViewController.tapFunction)

例子:

class DetailViewController: UIViewController {

    @IBOutlet weak var tripDetails: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        ...

        let tap = UITapGestureRecognizer(target: self, action: #selector(DetailViewController.tapFunction))
        tripDetails.isUserInteractionEnabled = true
        tripDetails.addGestureRecognizer(tap)
    }

    @objc
    func tapFunction(sender:UITapGestureRecognizer) {
        print("tap working")
    }
}

我必须使用@objc注释tap函数。 - Scott D. Strader

54

SWIFT 4 更新

 @IBOutlet weak var tripDetails: UILabel!

 override func viewDidLoad() {
    super.viewDidLoad()

    let tap = UITapGestureRecognizer(target: self, action: #selector(GameViewController.tapFunction))
    tripDetails.isUserInteractionEnabled = true
    tripDetails.addGestureRecognizer(tap)
}

@objc func tapFunction(sender:UITapGestureRecognizer) {

    print("tap working")
}

30

Swift 5

与@liorco类似,但需要用@IBAction替换@objc

class DetailViewController: UIViewController {

    @IBOutlet weak var tripDetails: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        ...

        let tap = UITapGestureRecognizer(target: self, action: #selector(DetailViewController.tapFunction))
        tripDetails.isUserInteractionEnabled = true
        tripDetails.addGestureRecognizer(tap)
    }

    @IBAction func tapFunction(sender: UITapGestureRecognizer) {
        print("tap working")
    }
}

这在Xcode 10.2上运作良好。


4
@IBAction 只需要将方法暴露给 Xcode 的 Interface Builder(因此 IB)。它也充当 @objc,但如果您使用代码添加手势或其他操作,则应使用 @objc 注释。 - Adam

16

好的便捷解决方案:

在您的 ViewController 中:

@IBOutlet weak var label: LabelButton!

override func viewDidLoad() {
    super.viewDidLoad()

    self.label.onClick = {
        // TODO
    }
}

您可以将此代码放置在您的 ViewController 或另一个 .swift 文件中(例如 CustomView.swift):

您可以将此代码放置在您的 ViewController 或另一个 .swift 文件中(例如 CustomView.swift):

@IBDesignable class LabelButton: UILabel {
    var onClick: () -> Void = {}
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        onClick()
    }
}

在Storyboard中选择Label,在右侧窗格的“Identity Inspector”中选择类别为LabelButton。

不要忘记在标签属性检查器中启用“用户交互功能已启用”


1
在viewDidLoad()中,如果没有效果,需要添加以下代码行:self.label.isUserInteractionEnabled = true。 - Touhid

16

Swift 3 更新

yourLabel.isUserInteractionEnabled = true

1
这并没有对我有帮助。我正在尝试在tableview的标签上完成它。 - Pavlos
即使在Storyboard中已经设置了,我也让它在这里正常工作了。 - brainray

4
你需要启用该标签的用户交互功能......
例如:
yourLabel.userInteractionEnabled = true

这个没有帮助我。我正在尝试在一个表格视图中的标签上实现它。 - Pavlos

3
对于Swift 3.0,您还可以更改手势长按时间。
label.isUserInteractionEnabled = true
let longPress:UILongPressGestureRecognizer = UILongPressGestureRecognizer.init(target: self, action: #selector(userDragged(gesture:))) 
longPress.minimumPressDuration = 0.2
label.addGestureRecognizer(longPress)

3

感谢研究员

这是我使用UIKit进行程序化用户界面的解决方案。

我只尝试过在Swift 5上运行,并且它有效。

有趣的事实是,您不必明确设置isUserInteractionEnabled = true

import UIKit

open class LabelButon: UILabel {
    var onClick: () -> Void = {}
    
    public override init(frame: CGRect) {
        super.init(frame: frame)
        isUserInteractionEnabled = true
    }
    
    public required init?(coder: NSCoder) {
        super.init(coder: coder)
    }
    
    public convenience init() {
        self.init(frame: .zero)
    }
    
    open override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        onClick()
    }
}

用途:

override func viewDidLoad() {
    super.viewDidLoad()
    
    let label = LabelButton()
    label.text = "Label"
    label.onClick = {
        // TODO
    }
}

不要忘记设置约束条件,否则它不会出现在视图中。

2
很容易被忽视,就像我一样,但不要忘记使用UITapGestureRecognizer而不是UIGestureRecognizer
最初的回答: 很容易被忽略,就像我的情况一样,但别忘了使用UITapGestureRecognizer而不是UIGestureRecognizer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接