Quiero emular un botón de presión larga, ¿cómo puedo hacer esto? Creo que se necesita un temporizador. Ya veo, UILongPressGestureRecognizer
pero ¿cómo puedo utilizar este tipo?
ios
objective-c
uibutton
long-press
Andrea
fuente
fuente
if(gesture.state == UIGestureRecognizerStateBegan)
, porque el usuario espera que suceda algo cuando todavía están presionando (el estado Comenzó), no cuando sueltan (Terminado).Como alternativa a la respuesta aceptada, esto se puede hacer muy fácilmente en Xcode usando Interface Builder.
Simplemente arrastre un Reconocimiento de gestos de pulsación larga desde la Biblioteca de objetos y suéltelo en la parte superior del botón donde desee la acción de pulsación larga.
A continuación, conecte una acción del Reconocimiento de gestos de pulsación larga que acaba de agregar a su controlador de vista, seleccionando el remitente para que sea del tipo
UILongPressGestureRecognizer
. En el código de eseIBAction
use esto, que es muy similar al código sugerido en la respuesta aceptada:En Objective-C :
if ( sender.state == UIGestureRecognizerStateEnded ) { // Do your stuff here }
O en Swift :
if sender.state == .Ended { // Do your stuff here }
Pero debo admitir que después de probarlo, prefiero la sugerencia hecha por @shengbinmeng como comentario a la respuesta aceptada, que era usar:
En Objective-C :
if ( sender.state == UIGestureRecognizerStateBegan ) { // Do your stuff here }
O en Swift :
if sender.state == .Began { // Do your stuff here }
La diferencia es que con
Ended
, ves el efecto de la pulsación larga cuando levantas el dedo. ConBegan
, verá el efecto de la pulsación larga tan pronto como el sistema capte la pulsación larga, incluso antes de levantar el dedo de la pantalla.fuente
Versión rápida de la respuesta aceptada
Hice la modificación adicional de usar en
UIGestureRecognizerState.Began
lugar de,.Ended
ya que eso es probablemente lo que la mayoría de los usuarios esperarían naturalmente. Pruébalos ambos y compruébalo por ti mismo.import UIKit class ViewController: UIViewController { @IBOutlet weak var button: UIButton! override func viewDidLoad() { super.viewDidLoad() // add gesture recognizer let longPress = UILongPressGestureRecognizer(target: self, action: #selector(longPress(_:))) self.button.addGestureRecognizer(longPress) } func longPress(gesture: UILongPressGestureRecognizer) { if gesture.state == UIGestureRecognizerState.began { print("Long Press") } } @IBAction func normalButtonTap(sender: UIButton) { print("Button tapped") } }
fuente
Prueba esto:
Añadiendo un botón
viewDidLoad:
como a continuación-(void)viewDidLoad { UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [btn setTag:1]; //you can set any integer value as tag number btn.title = @"Press Me"; [btn setFrame:CGRectMake(50.0, 50.0, 60.0, 60.0)]; // now create a long press gesture UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPressTap:)]; [btn addGestureRecognizer:longPress]; }
Ahora llama al método de gestos así
-(void)longPressTap:(id)sender { UIGestureRecognizer *recognizer = (UIGestureRecognizer*) sender // Recogniser have all property of button on which you have clicked // Now you can compare button's tag with recogniser's view.tag // View frame for getting the info on which button the click event happened // Then compare tag like this if(recognizer.view.tag == 1) { // Put your button's click code here } // And you can also compare the frame of your button with recogniser's view CGRect btnRect = CGRectMake(50.0, 50.0, 60.0, 60.0); if(recogniser.view.frame == btnRect) { //put your button's click code here } // Remember frame comparing is alternative method you don't need to write frame comparing code if you are matching the tag number of button }
fuente
recognizer.view.tag
me da una etiqueta incorrecta de UIButton hecho clic. ¿Alguna solución?Creo que necesitas mi solución.
debe tener este código para una sola pulsación
- (IBAction)buttonDidPress:(id)sender { NSLog("buttonDidPress"); }
primero, agregue un gesto de presión larga al botón
- (void)viewWillAppear:(BOOL)animated { UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(buttonDidLongPress:)]; [self.button addGestureRecognizer:longPress]; }
luego, llame al evento de pulsación única repetidamente si se reconoce el gesto de pulsación larga.
- (void)buttonDidLongPress:(UILongPressGestureRecognizer*)gesture { switch (gesture.state) { case UIGestureRecognizerStateBegan: { self.timer = [NSTimer timerWithTimeInterval:0.1 target:self selector:@selector(buttonDidPress:) userInfo:nil repeats:YES]; NSRunLoop * theRunLoop = [NSRunLoop currentRunLoop]; [theRunLoop addTimer:self.timer forMode:NSDefaultRunLoopMode]; } break; case UIGestureRecognizerStateEnded: { [self.timer invalidate]; self.timer = nil; } break; default: break; } }
fuente
UIGestureRecognizer
durante elviewWillAppear
ciclo de vida porque cada vez que aparece la vista, se agregará otro reconocedor de gestos. Esto debe hacerse en un método privado que se llama durante la inicialización.Para Swift 4, es necesario cambiar "func longPress" para que funcione:
import UIKit class ViewController: UIViewController { @IBOutlet weak var button: UIButton! override func viewDidLoad() { super.viewDidLoad() // add guesture recognizer let longPress = UILongPressGestureRecognizer(target: self, action: #selector(longPress(_:))) self.button.addGestureRecognizer(longPress) } @objc func longPress(_ guesture: UILongPressGestureRecognizer) { if guesture.state == UIGestureRecognizerState.began { print("Long Press") } } @IBAction func normalButtonTap(sender: UIButton) { print("Button tapped") } }
fuente
Respuesta de una línea, sin gestos:
[btn addTarget:self action:@selector(handleTouch:) forControlEvents:UIControlEventTouchDown | UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
Detalles: Esta active su objetivo en tres eventos: 1- Inmediatamente una vez que toques dedo hacia abajo el botón:
UIControlEventTouchDown
. Esto captura el inicio de pulsaciones largas. 2 y 3- Cuando el usuario levanta el dedo:UIControlEventTouchUpOutside
&UIControlEventTouchUpInside
. Esto captura el final de la prensa del usuario.Nota: esto funciona bien si no le importa la información adicional proporcionada por el reconocedor de gestos (por ejemplo, la ubicación del toque, etc.)
Puede agregar más eventos intermedios si es necesario, verlos todos aquí https://developer.apple.com/documentation/uikit/uicontrolevents?language=objc .
En Storyboard: conecte su botón a los 3 eventos, no solo al predeterminado que Storyboard selecciona (Touch Up Inside).
fuente
Tengo un UIButton subclasificado para mi aplicación, así que he sacado mi implementación. Puede agregar esto a su subclase o esto podría recodificarse fácilmente como una categoría UIButton.
Mi objetivo era agregar la pulsación larga a mi botón sin saturar mis controladores de vista con todo el código. Decidí que la acción debería llamarse cuando comience el estado del reconocedor de gestos.
Hay una advertencia que sale y que nunca me he molestado en resolver. Dice que es una posible fuga, creo que he probado el código y no se filtra.
@interface MYLongButton () @property (nonatomic, strong) UILongPressGestureRecognizer *gestureRecognizer; @property (nonatomic, strong) id gestureRecognizerTarget; @property (nonatomic, assign) SEL gestureRecognizerSelector; @end @implementation MYLongButton - (void)addLongPressTarget:(CGFloat)interval target:(id)target action:(SEL)selector { _gestureRecognizerTarget = target; _gestureRecognizerSelector = selector; _gestureRecognizer = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(handleLongPressGestureRecognizer:)]; _gestureRecognizer.minimumPressDuration = interval; [self addGestureRecognizer:_gestureRecognizer]; } - (void)handleLongPressGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer { if (gestureRecognizer.state == UIGestureRecognizerStateBegan) { NSAssert([_gestureRecognizerTarget respondsToSelector:_gestureRecognizerSelector], @"target does not respond to selector"); self.highlighted = NO; // warning on possible leak -- can anybody fix it? [_gestureRecognizerTarget performSelector:_gestureRecognizerSelector withObject:self]; } }
Para asignar la acción, agregue esta línea a su método viewDidLoad.
[_myLongButton addLongPressTarget:0.75 target:self selector:@selector(longPressAction:)];
La acción debe definirse como todas las IBActions (sin la IBAction).
- (void)longPressAction:(id)sender { // sender is the button }
fuente
Ninguno funcionó, por lo tanto, intenté escribir código de pulsación larga
IBAction
o hacer clicstoryboard
en el botón desde adentro enController
lugar de escribir enviewDidLoad
- (IBAction)btnClick:(id)sender { tag = (int)((UIButton *)sender).tag; // Long press here instead of in viewDidLoad UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)]; longPress.cancelsTouchesInView = NO; [sender addGestureRecognizer:longPress]; }
fuente