Как заставить UILabel отвечать на касание?

94

Я обнаружил, что могу создавать UILabel намного быстрее, чем UITextField, и большую часть времени планирую использовать UILabel для своего приложения для отображения данных.

Короче говоря, я хочу позволить пользователю нажать на UILabel и получить ответ на мой обратный вызов. Это возможно?

Спасибо.

Счастливый
источник
2
Вам нужно уточнитьuserInteractionEnabled = true
onmyway133

Ответы:

210

Вы можете добавить UITapGestureRecognizerэкземпляр в свой UILabel.

Например:

UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(labelTapped)];
tapGestureRecognizer.numberOfTapsRequired = 1;
[myLabel addGestureRecognizer:tapGestureRecognizer];
myLabel.userInteractionEnabled = YES;
pythonquick
источник
14
Ага, свойство userInteractionEnabled здесь является ключевым (поскольку другая конфигурация может и должна быть предпочтительно установлена ​​в раскадровках). По умолчанию пометьте, что взаимодействие отключено, чтобы через них проходили прикосновения, но в этом случае им нужно наблюдать за прикосновениями, чтобы активировался распознаватель жестов. Благодарность!
Marchy
1
Хороший! Я просто нажимал на ярлык и совершенно забыл включить взаимодействие с пользователем. Благодарность!
Майк Кричли
37

Если вы используете раскадровки, вы можете выполнить весь этот процесс в раскадровке без дополнительного кода. Добавьте метку к раскадровке, затем добавьте жест касания к метке. На панели "Утилиты" убедитесь, что для метки установлен флажок "Взаимодействие с пользователем включено". С помощью жеста касания (в нижней части контроллера представления на раскадровке) нажмите ctrl + щелкните и перетащите в файл ViewController.h и создайте действие. Затем реализуйте действие в файле ViewController.m.

Leenyburger
источник
Метод также доступен с использованием только конструктора интерфейсов без раскадровки
Гомино
Убедитесь, что «Взаимодействие с пользователем включено» отмечено в разделе « Просмотр » в инспекторе атрибутов , а не только в специальных возможностях.
SeanR
17

Swift 3.0

Инициализировать жест для tempLabel

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

Приемник действий

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

Swift 4.0

Инициализировать жест для tempLabel

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

Приемник действий

func actionTapped(_ sender: UITapGestureRecognizer) {
    // code here
}
Кушик
источник
Как получить текст метки от объекта-отправителя? Другими словами, как определить отправителя?
Vineel
Версия Swift 4 имеет @selector вместо #selector.
Кирби Тодд,
8

Swift 2.0:

Я добавляю строку nsmutable в качестве текста sampleLabel, обеспечивая взаимодействие с пользователем, добавляю жест касания и запускаю метод.

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
источник
4

Вместо этого вы можете использовать UIButton и установить желаемый текст. Кнопка не обязательно должна выглядеть как кнопка, если вы не хотите

Мэтт С.
источник
1
Что касается этого, у меня всегда были проблемы с UIButton, выравнивающим по левому краю многострочный текст. Даже когда я выставляю левое выравнивание по центру, это все равно происходит.
Happy
Я все же попробовал UIButton, и это довольно приятно. Проблема только в многострочных кнопках. Спасибо.
Happy
3

Чтобы добавить жест касания в 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];   

и оценить метод выбора

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

}

Примечание: добавьте UIGestureRecognizerDelegate в файл .h

Хардик Таккар
источник
2

Быстрая версия: var tapGesture : UITapGestureRecognizer = UITapGestureRecognizer()

Затем внутри viewDidLoad()добавьте это:

  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:")
Адитья Джха
источник
1

Если вы хотите использовать многострочный текст в своей кнопке, создайте UILabelмногострочный текст и добавьте его в качестве подпредставления на кнопку.

например:

yourLabel=[Uilabel alloc]init];
yourLabel.frame=yourButtom.Frame;//(frame size should be equal to your button's frame)
[yourButton addSubView:yourLabel]
Чандрамани
источник
1

Swift 3 от Элвина Джорджа

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")
}
М.Рустамзаде
источник
0

Версия Swift выглядит так:

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
источник
0

Лично я предпочитаю метод написания расширения для UILabel. Это то, что я использую.

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

Затем вы могли бы использовать его так из любого экземпляра UILabel:

myLabel.setOnTapped {
    // do something
}

Я считаю, что это потенциально может вызвать некоторые утечки памяти, но я еще не определил, как лучше всего их решить.

Натан Ф.
источник