¿Cómo hacer que UILabel responda al tap?

94

He descubierto que puedo crear UILabel mucho más rápido que UITextField y planeo usar UILabel la mayor parte del tiempo para mi aplicación de visualización de datos.

Sin embargo, para abreviar la historia, deseo permitir que el usuario toque un UILabel y que mi devolución de llamada responda a eso. ¿Es eso posible?

Gracias.

Contento
fuente
1
Necesita especificaruserInteractionEnabled = true
onmyway133

Respuestas:

208

Puede agregar una UITapGestureRecognizerinstancia a su UILabel.

Por ejemplo:

UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(labelTapped)];
tapGestureRecognizer.numberOfTapsRequired = 1;
[myLabel addGestureRecognizer:tapGestureRecognizer];
myLabel.userInteractionEnabled = YES;
pitón rápido
fuente
13
Ajá, la propiedad 'userInteractionEnabled' aquí es clave (ya que la otra configuración puede y debe establecerse preferiblemente en guiones gráficos). Label tiene la interacción predeterminada en desactivada para pasar los toques a través de ellos, pero en este caso deben observar los toques para que se active el reconocedor de gestos. ¡Gracias!
Marchy
1
¡Buena esa! Solo estaba tocando una etiqueta y me olvidé por completo de permitir la interacción del usuario. ¡Gracias!
Mike Critchley
37

Si está utilizando guiones gráficos, puede hacer todo este proceso en el guión gráfico sin código adicional. Agregue una etiqueta al guión gráfico, luego agregue un gesto de toque a la etiqueta. En el panel Utilidades, asegúrese de que la etiqueta "Interacción del usuario habilitada" esté marcada. Desde el gesto de toque (en la parte inferior de su controlador de vista en el guión gráfico), presione Ctrl + clic y arrastre a su archivo ViewController.h y cree una Acción. Luego, implemente la acción en el archivo ViewController.m.

leenyburger
fuente
El método también está disponible usando el generador de interfaces solo sin guiones gráficos
Gomino
Asegúrese de que "Interacción del usuario habilitada" esté marcada en la sección Ver en el inspector de atributos , no solo en los rasgos de accesibilidad.
SeanR
17

Swift 3.0

Inicializar el gesto para tempLabel

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

Receptor de acción

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

Swift 4.0

Inicializar el gesto para tempLabel

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

Receptor de acción

func actionTapped(_ sender: UITapGestureRecognizer) {
    // code here
}
Koushik
fuente
¿Cómo obtener el texto de la etiqueta del objeto remitente? En otras palabras, ¿cómo identificar al remitente?
Vineel
La versión Swift 4 tiene @selector en lugar de #selector.
Kirby Todd
8

Swift 2.0:

Estoy agregando una cadena nsmutable como texto de sampleLabel, permitiendo la interacción del usuario, agregando un gesto de toque y activando un 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")
}
AG
fuente
4

En su lugar, puede usar un UIButton y configurar el texto como desee. El botón no tiene que verse como un botón si no quieres

Matt S.
fuente
1
En cuanto a eso, siempre he tenido problemas con UIButton para justificar el texto de varias líneas a la izquierda. Incluso cuando configuro la alineación izquierda en el centro, todavía sucede.
Feliz
Sin embargo, probé UIButton y es bastante bueno. Son solo los botones de varias líneas los que son un problema. Gracias.
Feliz
3

Para agregar el gesto Tap en 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];   

y evaluar el método selector

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

}

Nota: agregue UIGestureRecognizerDelegate en el archivo .h

Hardik Thakkar
fuente
2

Versión rápida: var tapGesture : UITapGestureRecognizer = UITapGestureRecognizer()

Luego viewDidLoad(), adentro , agregue esto:

  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
fuente
1

Si desea utilizar texto de varias líneas en su botón, cree un texto de varias líneas UILabely agréguelo como una subvista en su botón.

por ejemplo:

yourLabel=[Uilabel alloc]init];
yourLabel.frame=yourButtom.Frame;//(frame size should be equal to your button's frame)
[yourButton addSubView:yourLabel]
Chandramani
fuente
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
fuente
0

La versión Swift se ve así:

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
fuente
0

Personalmente prefiero el método de escribir una extensión para UILabel. Esto es lo que utilizo.

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

Luego lo usaría así desde cualquier instancia de UILabel:

myLabel.setOnTapped {
    // do something
}

Esto puede potencialmente causar algunas pérdidas de memoria, creo, pero aún no he determinado la mejor manera de resolverlas.

Nathan F.
fuente