UIButton Uzun Basın Etkinliği


86

Uzun bir basma düğmesi taklit etmek istiyorum, bunu nasıl yapabilirim? Sanırım bir zamanlayıcıya ihtiyaç var. Anlıyorum UILongPressGestureRecognizerama bu türü nasıl kullanabilirim?

Yanıtlar:


160

Örneği oluşturup UILongPressGestureRecognizerdüğmeye ekleyerek başlayabilirsiniz .

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

Ve sonra hareketi işleyen yöntemi uygulayın

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

Şimdi bu temel yaklaşım olacaktır. Ayrıca minimum baskı süresini ve ne kadar hatanın tolere edilebileceğini de ayarlayabilirsiniz. Ayrıca, hareketi tanıdıktan sonra yöntemin birkaç kez çağrıldığını ve sonunda bir şey yapmak istiyorsanız, durumunu kontrol etmeniz ve halletmeniz gerekeceğini unutmayın.


Süper! Teşekkürler! Btw: if (jest.state == UIGestureRecognizerStateEnded) çok önemlidir, aksi takdirde longPress boşluğunuzda pek çok olay alırsınız
RecycleRobot

30
Kullanmak isteyebilirsiniz if(gesture.state == UIGestureRecognizerStateBegan), çünkü kullanıcı (Bitti) bıraktığında değil, hala bastığında (Başlayan durumu) bir şey olmasını bekler.
shengbinmeng

28

Kabul edilen cevaba alternatif olarak bu, Interface Builder kullanılarak Xcode'da çok kolay bir şekilde yapılabilir.

Sadece bir sürükle Uzun basın Gesture Tanıyıcı gelen Nesne Kitaplığı ve uzun basma eylemini istediğiniz düğmenin üstüne bırakın.

Daha sonra, yeni eklenen Uzun Basma Hareketi Tanıyıcıdan bir Eylemi , göndereni türünden seçerek görünüm denetleyicinize bağlayın UILongPressGestureRecognizer. Bunun kodunda IBAction, kabul edilen cevapta önerilen koda çok benzeyen şunu kullanın:

In Objective-C :

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

Veya Swift ile :

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

Ama itiraf etmeliyim ki, denedikten sonra, @shengbinmeng tarafından yapılan öneriyi, kabul edilen cevaba bir yorum olarak tercih ediyorum.

In Objective-C :

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

Veya Swift ile :

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

Aradaki fark, Endedparmağınızı kaldırdığınızda uzun basmanın etkisini görmenizdir. İle Began, daha parmağınızı ekrandan kaldırmadan önce, uzun basma sistem tarafından yakalanır yakalanmaz uzun basmanın etkisini görürsünüz.


18

Kabul edilen cevabın hızlı versiyonu

Muhtemelen çoğu kullanıcının doğal olarak bekleyeceği şey olduğu için kullanmak UIGestureRecognizerState.Beganyerine ek bir değişiklik yaptım .Ended. İkisini de deneyin ve kendiniz görün.

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

10

Bunu dene:

viewDidLoad:Aşağıdaki gibi düğme eklemek

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

Şimdi hareket yöntemini şöyle çağırın

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

recognizer.view.tagbana tıklanan UIButton'un yanlış etiketini veriyor. Herhangi bir çözüm?
rohan-patel

3

Sanırım benim çözümüme ihtiyacın var.

tek basış için bu koda sahip olmalısınız

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

ilk olarak, düğmeye uzun basma hareketi ekleyin

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

ardından uzun basma hareketi algılanırsa tek basma olayını tekrar tekrar çağırın.

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

Yaşam döngüsü UIGestureRecognizersırasında viewWillAppearolayını eklememelisiniz çünkü görünüm her göründüğünde başka bir hareket tanıyıcı eklenecektir. Bu, başlatma sırasında çağrılan özel bir yöntemde yapılmalıdır.
WikipediaBrown

3

Swift 4 için, çalışması için "func longPress" in değiştirilmesi gerekir:

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

1

Hareket olmaksızın tek satırlık cevap:

[btn addTarget:self action:@selector(handleTouch:) forControlEvents:UIControlEventTouchDown | UIControlEventTouchUpInside | UIControlEventTouchUpOutside];

Detaylar: Bu üç olaylara hedef tetikler: 1- Hemen aşağı düğmesine parmak dokunuşları kez: UIControlEventTouchDown. Bu, uzun basış başlangıcını yakalar. 2 & 3- Kullanıcı parmağını kaldırdığında: UIControlEventTouchUpOutside& UIControlEventTouchUpInside. Bu, kullanıcı basınının sonunu yakalar.

Not: Bu, hareket tanıyıcı tarafından sağlanan ekstra bilgi (ör. Dokunma konumu, vb.) Umurunuzda değilse işe yarar.

Gerekirse daha fazla ara etkinlik ekleyebilirsiniz, hepsini burada https://developer.apple.com/documentation/uikit/uicontrolevents?language=objc görün .

Storyboard'da: Düğmenizi yalnızca Storyboard'un seçtiği varsayılan (İçeride Rötuş Yap) değil, 3 etkinliğe bağlayın.

Film şeridinde 3 olay


0

Uygulamam için alt sınıf bir UIButton'ım var, bu yüzden uygulamamı çıkardım. Bunu alt sınıfınıza ekleyebilirsiniz veya bu, bir UIButton kategorisi kadar kolay bir şekilde yeniden kodlanabilir.

Amacım, görünüm denetleyicilerimi tüm kodla karıştırmadan düğmeme uzun basmayı eklemekti. Hareket tanıma durumu başladığında eylemin çağrılması gerektiğine karar verdim.

Çözmeye hiç zahmet etmediğime dair bir uyarı geliyor. Olası bir sızıntı olduğunu söylüyor, kodu test ettiğimi ve sızıntı olmadığını düşündüm.

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

Eylemi atamak için bu satırı viewDidLoad yönteminize ekleyin.

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

Eylem, tüm IBActions gibi (IBAction olmadan) tanımlanmalıdır.

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

0

Yok dolayısıyla çalıştı ben de longpress kod yazarken çalıştı IBActiongelen tıklama veya düğme storyboardiçinde Controlleryerine yazmaviewDidLoad

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

}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.