Manejar el evento táctil en UILabel y conectarlo a una IBAction

101

Ok, tengo un UILabelgenerador de interfaz creado que muestra un texto predeterminado de "toque para comenzar".

Cuando el usuario toca UILabelQuiero que active un método IBAction: -(IBAction)next;que actualiza el texto de la etiqueta para decir algo nuevo.
Sería realmente conveniente si esto me permitiera simplemente arrastrar una conexión desde mi método a mi etiqueta y luego seleccionar retocar adentro, como con un botón. pero, ay, no hay cigarro.

así que de todos modos, supongo que mi pregunta es, ¿tendré que hacer una subclase UILabelpara que esto funcione? ¿O hay alguna forma de que pueda arrastrar un botón sobre la etiqueta, pero hacerlo 0% opaco? ¿O hay una solución más simple que me falta?

wfbarksdale
fuente

Respuestas:

255

Echale un vistazo:

UILabel *label = ...
label.userInteractionEnabled = YES;
UITapGestureRecognizer *tapGesture =
      [[UITapGestureRecognizer alloc] initWithTarget:self 
                                              action:@selector(labelTap)];
[label addGestureRecognizer:tapGesture];

El truco consiste en permitir la interacción del usuario.

Scott Persinger
fuente
1
¿Qué pasa si tengo varias etiquetas? ¿Cómo puedo diferenciar cuál fue aprovechado?
alumno
1
@learner prueba la propiedad de la etiqueta. asegúrese de usar labelTap: en lugar de labelTap. y use - (void) labelTap: (id) sender ;.
thedjaney
1
@thedjaney El remitente es UITapGestureRecognizer, no UILabel
h4labs
TapGestureRecognizer no es lo mismo que retocar el interior y pierde la conformidad y accesibilidad de la interfaz humana.
1
@ h4labs puede usar UITapGestureRecognizer * tapGesture = sender; luego obtenga la etiqueta con tapGesture.view.tag
DJTano
70

UILabel hereda de UIView que hereda de UIResponder. Todos los objetos UIresponder pueden manejar eventos táctiles. Entonces, en su archivo de clase que conoce su vista (que contiene la etiqueta UI) implemente:

-(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event;

En el generador de interfaces, establezca el valor de la etiqueta de UILabel. cuando se produzcan toques en su método touchesBegan, verifique el valor de la etiqueta de la vista a la que pertenece la etiqueta:

UITouch *touch = [touches anyObject];

if(touch.view.tag == MY_TAG_VAL)
label.text = @"new text";

Conecta su código en su archivo de clase con el objeto UILabel en el constructor de interfaces declarando su variable de instancia UILabel con el prefijo IBOutlet:

IBOutlet UILabel *label;

Luego, en el generador de interfaces, puede conectarlos.

Agente de mudanzas
fuente
31
Una nota, debe asegurarse de marcar "Interacción del usuario habilitada" en el generador de interfaces, o esto no funcionará.
midas06
Encontré un problema con este método. Funcionó bien cuando el controlador de vista se cargó directamente, pero cuando creé un controlador de navegación, empujé el controlador que contiene la etiqueta al controlador de navegación y luego lo mostré, los toques ya no parecen llegar a la etiqueta. ¿Algunas ideas?
midas06
si es la misma clase de controlador de vista que está presionando, debería funcionar. Parece que puede haber algún otro pequeño problema. tal vez comience otra pregunta y publique algún código
Remover
5
Un método similar que no requiere etiquetas es simplemente verificar si touch.view es igual a la salida que configuró para la etiqueta. Prefiero esto, ya que significa que no tengo que realizar un seguimiento de las etiquetas.
Desfragmentado el
gran solucion. Le recomiendo que no establezca ninguna etiqueta en 0 porque hacer clic en cualquier otro lugar tiene un valor de etiqueta de 0. Esto se debe a que su vista probablemente tendrá un valor de etiqueta de 0. De lo contrario, puede establecer la etiqueta de su vista en algo como -1 y luego puede usar el valor de etiqueta de 0 en otro lugar, es decir, un botón
kevinl
30

Puede usar un UIButton, hacerlo transparente, es decir, tipo personalizado sin una imagen, y agregarle un UILabel (centrado). Luego conecte los eventos de botón normales.

Eiko
fuente
Estoy de acuerdo, el tipo de botón personalizado debería brindarle una experiencia de usuario de tipo UILabel.
Stitz
2
+1, agradable y simple. Había intentado esto antes configurando un botón normal en opacidad 0 que no funcionó, pero la sugerencia para cambiar el tipo a personalizado funcionó perfectamente.
Brian Moeskau
La opacidad afectará el botón y todas sus subvistas, por lo que opacity = 0 hará que todo sea invisible.
Eiko
10
¡Ay! Este es un truco en comparación con las otras soluciones en este hilo. Utilice un reconocedor de gestos de toque en una etiqueta si desea reconocer un gesto de toque en una etiqueta. (¿Ves cómo se lee como si estuviera destinado a esto?)
James Boutcher
Esta es una solución mucho, mucho mejor porque los botones se encargan de los retoques en el interior en lugar de solo tocar (comenzar).
17

Swift 3

Tienes un IBOutlet

@IBOutlet var label: UILabel!

En el que habilita la interacción del usuario y agrega un reconocedor de gestos

label.isUserInteractionEnabled = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(userDidTapLabel(tapGestureRecognizer:)))
label.addGestureRecognizer(tapGesture)

Y finalmente, maneja el grifo

func userDidTapLabel(tapGestureRecognizer: UITapGestureRecognizer) {
  // Your code goes here
}
César Cruz
fuente
2
Tuve que agregar @objc a userDidTapLabel para que esto funcione. Podría ser algo rápido.
Cumple con POSIX