Pregunta UIButton Long Press Event


Quiero emular un botón de presión prolongado, ¿cómo puedo hacer esto? Creo que se necesita un temporizador. Ya veo UILongPressGestureRecognizer pero ¿cómo puedo utilizar este tipo?


74
2018-05-30 17:52


origen


Respuestas:


Puede comenzar creando y adjuntando UILongPressGestureRecognizer instancia al botón.

UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
[self.button addGestureRecognizer:longPress];
[longPress release];

Y luego implementa el método que maneja el gesto

- (void)longPress:(UILongPressGestureRecognizer*)gesture {
    if ( gesture.state == UIGestureRecognizerStateEnded ) {
         NSLog(@"Long Press");
    }
}

Ahora este sería el enfoque básico. También puede establecer la duración mínima de la prensa y la cantidad de error tolerable. Y también tenga en cuenta que el método se llama pocas veces si después de reconocer el gesto, por lo que si desea hacer algo al final del mismo, deberá verificar su estado y manejarlo.


149
2018-05-30 18:27



Como alternativa a la respuesta aceptada, esto se puede hacer muy fácilmente en Xcode usando Interface Builder.

Solo arrastre una Long Press Gesture Recognizer desde el Biblioteca de objetos y colóquelo sobre el botón donde desea la acción de pulsación larga.

A continuación, conecte una Acción de Long Press Gesture Recognizer acaba de agregar, a su controlador de vista, seleccionando el remitente para que sea de tipo UILongPressGestureRecognizer. En el código de eso IBAction use esto, que es muy similar al código sugerido en la respuesta aceptada:

En C objetivo:

if ( sender.state == UIGestureRecognizerStateEnded ) {
     // Do your stuff here
}

O en Rápido:

if sender.state == .Ended {
    // Do your stuff here
}

Pero tengo que admitir que después de probarlo, prefiero la sugerencia hecha por @shengbinmeng como un comentario a la respuesta aceptada, que era usar:

En C objetivo:

if ( sender.state == UIGestureRecognizerStateBegan ) {
     // Do your stuff here
}

O en Rápido:

if sender.state == .Began {
    // Do your stuff here
}

La diferencia es que con Ended, ves el efecto de la presión larga cuando levantas el dedo. Con Began, verá el efecto de la pulsación larga tan pronto como el sistema capte la presión prolongada, incluso antes de levantar el dedo de la pantalla.


21
2017-11-05 12:18



Versión rápida de la respuesta aceptada

Hice la modificación adicional de usar UIGestureRecognizerState.Began más bien que .Ended ya que eso es probablemente lo que la mayoría de los usuarios esperarían naturalmente. Pruébalos y ve por ti mismo, sin embargo.

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

11
2017-12-04 07:41



Prueba esto:

Agregar botón en viewDidLoad: como abajo

-(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 como este

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

8
2018-05-24 08:22



Creo que necesitas mi solución.

deberías tener este código para una sola pulsación

- (IBAction)buttonDidPress:(id)sender {
    NSLog("buttonDidPress");
}

primero, agregue el gesto de presionar prolongadamente 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 una sola pulsación repetidamente si se reconoce el gesto de la presión prolongada.

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

3
2018-02-13 11:58



Para Swift 4, el "func longPress" necesita ser cambiado 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")
    }
}

2
2017-09-22 13:53



Tengo un UIButton subclase para mi aplicación, así que he retirado mi implementación. Puede agregar esto a su subclase o esto podría ser fácilmente recodificado como una categoría UIButton.

Mi objetivo era agregar la presión prolongada a mi botón sin saturar mis controles de vista con todo el código. Decidí llamar a la acción cuando comienza el estado del reconocedor de gestos.

Hay una advertencia que sale que nunca me he molestado en resolver. Dice que es una posible fuga, pensé que probé el código y no se filtró.

@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 IBAcciones (sin IBAction).

- (void)longPressAction:(id)sender {
    // sender is the button
}

0
2017-12-08 10:20



Ninguno funcionó, por lo tanto intenté escribir el código longpress en IBAction o haga clic en el botón storyboard en Controller en lugar de escribir en viewDidLoad

- (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];

}

0