UIButton Long Press Event

Chcę emulować długi przycisk a, jak Mogę to zrobić? Myślę, że potrzebny jest zegar. Widzę UILongPressGestureRecognizer ale jak mogę wykorzystać ten typ?

Author: Suragch, 2011-05-30

8 answers

Możesz zacząć od utworzenia i dołączenia instancji UILongPressGestureRecognizer do przycisku.

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

A następnie zaimplementować metodę, która obsługuje gest

- (void)longPress:(UILongPressGestureRecognizer*)gesture {
    if ( gesture.state == UIGestureRecognizerStateEnded ) {
         NSLog(@"Long Press");
    }
}
To byłoby podstawowe podejście. Można również ustawić minimalny czas naciśnięcia przycisku i dopuszczalny poziom błędu. A także należy pamiętać, że metoda jest wywoływana kilka razy, jeśli po rozpoznaniu gest, więc jeśli chcesz zrobić coś na końcu, trzeba będzie sprawdzić jego stan i obsługiwać go.
 150
Author: Deepak Danduprolu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-30 18:27:38

Jako alternatywa dla zaakceptowanej odpowiedzi, można to zrobić bardzo łatwo w Xcode za pomocą Interface Builder.

Po prostu przeciągnij Długie naciśnięcie rozpoznawania gestówz biblioteki obiektów i upuść go na górze przycisku, w którym chcesz wykonać operację długiego naciśnięcia.

Następnie, podłącz akcję z Long Press gest recognition właśnie dodanego do kontrolera widoku, wybierając nadawcę, który ma być typu UILongPressGestureRecognizer. W kodzie tego IBAction Użyj tego, co jest bardzo podobne do kodu sugerowanego w zaakceptowanej odpowiedzi:

W Objective-C:

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

Lub w :

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

Ale muszę przyznać, że po wypróbowaniu wolę sugestię @ shengbinmeng jako komentarz do zaakceptowanej odpowiedzi, która miała posłużyć:

W Objective-C:

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

Lub w :

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

Różnica polega na tym, że z Ended, widzisz efekt długiego naciśnięcia, gdy podnosisz palec. Dzięki funkcji Began możesz zobaczyć efekt długiego naciśnięcia, gdy tylko system złapie długie naciśnięcie, nawet zanim zdejmiesz palec z ekranu.

 22
Author: alondono,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-14 23:21:27

Wersja Swift zaakceptowanej odpowiedzi

Wprowadziłem dodatkową modyfikację używania UIGestureRecognizerState.Began zamiast .Ended, ponieważ prawdopodobnie tego oczekuje większość użytkowników. Wypróbuj oba i przekonaj się sam.

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
Author: Suragch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-13 15:25:57

Spróbuj tego:

Dodawanie przycisku w viewDidLoad: Jak poniżej

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

Teraz wywołaj metodę gestów w ten sposób

-(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
Author: TheTiger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-02 07:28:44

Myślę, że potrzebujesz mojego rozwiązania.

Powinieneś mieć ten kod do pojedynczego naciśnięcia

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

Najpierw dodaj długie naciśnięcie gest do przycisku

- (void)viewWillAppear:(BOOL)animated
{
    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(buttonDidLongPress:)];
    [self.button addGestureRecognizer:longPress];
}

Następnie wywołaj Zdarzenie pojedynczego naciśnięcia wielokrotnie, jeśli rozpoznany jest gest długiego naciśnięcia.

- (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
Author: Jerry Juang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-24 08:22:26

Dla Swifta 4, "func longPress" musi zostać zmieniony, aby działał:

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
Author: Bevan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-13 12:03:54

Mam podklasowany UIButton dla mojej aplikacji, więc wycofałem moją implementację. Możesz dodać to do swojej podklasy lub może to być równie łatwo przekodowane jako kategoria UIButton.

Moim celem było dodanie długiego przycisku do mojego przycisku bez zaśmiecania kontrolerów widoku całym kodem. Zdecydowałem, że akcja powinna zostać wywołana, gdy zacznie się stan rozpoznawania gestów.

Pojawia się Ostrzeżenie, którego nigdy nie rozwiązałem. Mówi, że to możliwy wyciek., myślałem, że przetestowałem kod i nie przecieka.
@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];
    }
}

Aby przypisać akcję dodaj tę linię do metody viewDidLoad.

[_myLongButton addLongPressTarget:0.75 target:self selector:@selector(longPressAction:)];

Akcja powinna być zdefiniowana jak wszystkie IBActions (bez IBAction).

- (void)longPressAction:(id)sender {
    // sender is the button
}
 0
Author: Dan Loughney,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-22 13:53:02

Żaden nie zadziałał, dlatego próbowałem napisać kod longpress w IBAction lub kliknąć przycisk z storyboard w Controller zamiast pisać w 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
Author: karan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-08 10:20:52