Como fazer o UILabel responder ao toque?


94

Eu descobri que posso criar UILabel muito mais rápido do que UITextField e planejo usar UILabel na maioria das vezes para meu aplicativo de exibição de dados.

Para encurtar a história, porém, desejo permitir que o usuário toque em um UILabel e que meu retorno de chamada responda a isso. Isso é possível?

Obrigado.


1
Você precisa especificaruserInteractionEnabled = true
onmyway133,

Respostas:


208

Você pode adicionar uma UITapGestureRecognizerinstância ao seu UILabel.

Por exemplo:

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

13
Aha, a propriedade 'userInteractionEnabled' aqui é a chave (uma vez que a outra configuração pode e deve ser definida preferencialmente em storyboards). O padrão da etiqueta para desativar a interação de modo a passar os toques por meio deles - mas, neste caso, eles precisam observar os toques para que o reconhecedor de gestos seja ativado. Obrigado!
Marchy

1
Agradável! Eu estava apenas tocando em um rótulo e esqueci totalmente de permitir a interação do usuário. Obrigado!
Mike Critchley

37

Se estiver usando storyboards, você pode fazer todo esse processo no storyboard sem nenhum código adicional. Adicione um rótulo ao storyboard e, em seguida, adicione um gesto de toque ao rótulo. No painel Utilitários, certifique-se de que "Interação do usuário habilitada" esteja marcada para o rótulo. Com o gesto de toque (na parte inferior do controlador de visualização no storyboard), ctrl + clique e arraste para o arquivo ViewController.h e crie uma ação. Em seguida, implemente a ação no arquivo ViewController.m.


Método também disponível usando o construtor de interface sozinho sem storyboards
Gomino

Certifique-se de que a opção "Interação do usuário habilitada" esteja marcada na seção Exibir no inspetor de atributos , não apenas as características de acessibilidade.
SeanR

17

Swift 3.0

Inicialize o gesto para tempLabel

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

Receptor de ação

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

Swift 4.0

Inicialize o gesto para tempLabel

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

Receptor de ação

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

Como obter o texto do rótulo do objeto remetente? Em outras palavras, como identificar o remetente?
Vineel

A versão Swift 4 tem @selector em vez de #selector.
Kirby Todd

8

Swift 2.0:

Estou adicionando uma string nsmutável como texto do sampleLabel, permitindo a interação do usuário, adicionando um gesto de toque e acionar um método.

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

4

Você poderia usar um UIButton em vez disso e definir o texto como você deseja. O botão não precisa se parecer com um botão se você não quiser


1
Com relação a isso, sempre tive problemas com o UIButton justificando texto de várias linhas à esquerda. Mesmo quando eu defino o alinhamento à esquerda para o centro, ainda acontece.
Feliz

Eu dei uma chance ao UIButton e é muito bom. São apenas os botões multilinhas que são um problema. Obrigado.
Feliz

3

Para adicionar o gesto de toque em 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];   

e para avaliar o método seletor

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

}

Nota: Adicione UIGestureRecognizerDelegate no arquivo .h


2

Versão Swift: var tapGesture : UITapGestureRecognizer = UITapGestureRecognizer()

Então viewDidLoad(), dentro , adicione isto:

  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

Se você quiser usar texto UILabelmultilinha em seu botão, crie um com texto multilinha e adicione como uma subvisualização em seu botão.

por exemplo:

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

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

0

A versão Swift tem esta aparência:

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

0

Eu pessoalmente prefiro o método de escrever uma extensão para UILabel. É isso que eu uso.

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

Você então o usaria desta forma a partir de qualquer instância UILabel:

myLabel.setOnTapped {
    // do something
}

Acredito que isso possa causar alguns vazamentos de memória, mas ainda não determinei a melhor forma de resolvê-los.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.