Chcę emulować długie naciśnięcie przycisku, jak mogę to zrobić? Myślę, że potrzebny jest minutnik. Rozumiem, UILongPressGestureRecognizer
ale jak mogę wykorzystać ten typ?
ios
objective-c
uibutton
long-press
Andrea
źródło
źródło
if(gesture.state == UIGestureRecognizerStateBegan)
, ponieważ użytkownik oczekuje, że coś się stanie, gdy nadal naciskają (stan zaczął), a nie po zwolnieniu (zakończone).Jako alternatywę dla zaakceptowanej odpowiedzi można to zrobić bardzo łatwo w Xcode przy użyciu Interface Builder.
Po prostu przeciągnij narzędzie rozpoznawania gestów z długim naciśnięciem z biblioteki obiektów i upuść je na przycisku w miejscu, w którym ma zostać wykonane długie naciśnięcie.
Następnie połącz akcję z właśnie dodanego narzędzia do rozpoznawania gestów z długim naciśnięciem do kontrolera widoku, wybierając nadawcę, który ma być typu
UILongPressGestureRecognizer
. W kodzie tegoIBAction
użyj tego, który jest bardzo podobny do kodu sugerowanego w zaakceptowanej odpowiedzi:W celu C :
if ( sender.state == UIGestureRecognizerStateEnded ) { // Do your stuff here }
Lub w Swift :
if sender.state == .Ended { // Do your stuff here }
Muszę jednak przyznać, że po wypróbowaniu tego wolę sugestię @shengbinmeng jako komentarz do zaakceptowanej odpowiedzi, którą miałam użyć:
W celu C :
if ( sender.state == UIGestureRecognizerStateBegan ) { // Do your stuff here }
Lub w Swift :
if sender.state == .Began { // Do your stuff here }
Różnica polega na tym
Ended
, że po podniesieniu palca widać efekt długiego naciśnięcia. ZBegan
efektem długiego naciśnięcia widać, gdy tylko długie naciśnięcie zostanie złapane przez system, jeszcze przed oderwaniem palca od ekranu.źródło
Szybka wersja zaakceptowanej odpowiedzi
Wprowadziłem dodatkową modyfikację, używając
UIGestureRecognizerState.Began
zamiast.Ended
tego, ponieważ prawdopodobnie tego naturalnie spodziewałaby się 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") } }
źródło
Spróbuj tego:
Dodawanie przycisku
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 }
źródło
recognizer.view.tag
daje mi zły tag klikniętego przycisku UIButton. Jakieś rozwiązanie?Myślę, że potrzebujesz mojego rozwiązania.
powinieneś mieć ten kod dla pojedynczego naciśnięcia
- (IBAction)buttonDidPress:(id)sender { NSLog("buttonDidPress"); }
najpierw dodaj gest długiego naciśnięcia do przycisku
- (void)viewWillAppear:(BOOL)animated { UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(buttonDidLongPress:)]; [self.button addGestureRecognizer:longPress]; }
następnie wielokrotnie wywołuj zdarzenie pojedynczego naciśnięcia, jeśli zostanie rozpoznany 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; } }
źródło
UIGestureRecognizer
trakcieviewWillAppear
cyklu życia, ponieważ za każdym razem, gdy pojawi się widok, zostanie dodany inny aparat do rozpoznawania gestów. Należy to zrobić w metodzie prywatnej wywoływanej podczas inicjalizacji.W przypadku Swift 4 należy zmienić „func longPress”, 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") } }
źródło
Odpowiedź w jednym wierszu, bez gestów:
[btn addTarget:self action:@selector(handleTouch:) forControlEvents:UIControlEventTouchDown | UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
Szczegóły: To wyzwala swój cel na trzech imprezach: 1- Natychmiast po palec dotyka przycisk:
UIControlEventTouchDown
. To wychwytuje początek długich naciśnięć. 2 & 3- Gdy użytkownik podniesie palec:UIControlEventTouchUpOutside
&UIControlEventTouchUpInside
. To oddaje koniec prasy użytkownika.Uwaga: działa to dobrze, jeśli nie interesują Cię dodatkowe informacje dostarczane przez aparat rozpoznawania gestów (np. Lokalizacja dotyku itp.)
W razie potrzeby możesz dodać więcej wydarzeń pośrednich. Zobacz je wszystkie tutaj https://developer.apple.com/documentation/uikit/uicontrolevents?language=objc .
W Storyboard: Połącz swój przycisk z 3 wydarzeniami, a nie tylko domyślnym, które wybiera Storyboard (Touch Up Inside).
źródło
Mam podklasę UIButton dla mojej aplikacji, więc wyciągnąłem moją implementację. Możesz dodać to do swojej podklasy lub można to równie łatwo przekodować jako kategorię UIButton.
Moim celem było dodanie długiego naciśnięcia przycisku bez zaśmiecania kontrolerów widoku całym kodem. Zdecydowałem, że akcja powinna zostać wywołana, gdy rozpocznie się stan rozpoznawania gestów.
Pojawia się ostrzeżenie, którego nigdy nie próbowałem rozwiązać. Mówi, że to możliwy wyciek, myślałem, że przetestowałem kod i nie wycieka.
@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 swojej metody viewDidLoad.
[_myLongButton addLongPressTarget:0.75 target:self selector:@selector(longPressAction:)];
Akcję należy zdefiniować jak wszystkie IBActions (bez IBAction).
- (void)longPressAction:(id)sender { // sender is the button }
źródło
Żaden pracował stąd Próbowałem pisania kodu longpress w
IBAction
przycisk lub kliknięcie odstoryboard
wController
zamiast pisać wviewDidLoad
- (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]; }
źródło