UIButton長押しイベント


86

長押しボタンをエミュレートしたいのですが、どうすればよいですか?タイマーが必要だと思います。わかりましたUILongPressGestureRecognizerが、どうすればこのタイプを利用できますか?

回答:


160

UILongPressGestureRecognizerインスタンスを作成してボタンにアタッチすることから始めることができます。

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

そして、ジェスチャーを処理するメソッドを実装します

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

これが基本的なアプローチになります。プレスの最小時間と許容できるエラーの量を設定することもできます。また、ジェスチャを認識した後でメソッドが数回呼び出されるため、最後に何かを実行する場合は、その状態を確認して処理する必要があることにも注意してください。


素晴らしい!ありがとう!ところで:if(gesture.state == UIGestureRecognizerStateEnded)は非常に重要です。そうしないと、longPress voidで多くのイベントが発生します
RecycleRobot 2013年

29
if(gesture.state == UIGestureRecognizerStateBegan)ユーザーは、離したとき(終了)ではなく、まだ押しているとき(状態は開始)に何かが起こることを期待しているため、を使用することをお勧めします。
shengbinmeng 2014年

28

受け入れられた答えの代わりに、これはInterfaceBuilderを使用してXcodeで非常に簡単に行うことができます。

オブジェクトライブラリから長押しジェスチャ認識機能をドラッグし、長押しアクションが必要なボタンの上にドロップするだけです。

次に、追加した長押しジェスチャ認識機能からのアクションをView Controllerに接続し、タイプの送信者を選択しますUILongPressGestureRecognizer。そのコードでIBActionは、これを使用します。これは、受け入れられた回答で提案されたコードと非常によく似ています。

Objective-C

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

またはSwiftで

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

しかし、私はそれを試した後、受け入れられた答えへのコメントとして@shengbinmengによってなされた提案を好むことを認めなければなりません。

Objective-C

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

またはSwiftで

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

違いは、を使用するとEnded、指を離したときに長押しの効果が見られることです。を使用するBeganと、指を画面から離す前であっても、システムが長押しをキャッチするとすぐに長押しの効果を確認できます。


18

受け入れられた回答のSwiftバージョン

私が使用しての追加修正をしたUIGestureRecognizerState.Beganのではなく、.Endedそれはほとんどのユーザーが自然に期待するものでしょうからです。ただし、両方を試して、自分の目で確かめてください。

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

8

これを試して:

viewDidLoad:以下のようにボタンを追加します

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

このようにジェスチャーメソッドを呼び出します

-(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.tagクリックされたUIButtonの間違ったタグが表示されます。解決策はありますか?
rohan-patel 2013年

3

私の解決策が必要だと思います。

シングルプレス用にこのコードが必要です

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

まず、ボタンに長押しジェスチャーを追加します

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

次に、長押しのジェスチャが認識された場合は、シングルプレスイベントを繰り返し呼び出します。

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

ビューが表示されるたびに別のジェスチャ認識機能が追加されるためUIGestureRecognizerviewWillAppearライフサイクルイベント中にを追加しないでください。これは、初期化中に呼び出されるプライベートメソッドで実行する必要があります。
WikipediaBrown

3

Swift 4の場合、機能させるには「funclongPress」を変更する必要があります。

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

ジェスチャーなしの1行の回答:

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

詳細: これにより、次の3つのイベントでターゲットがトリガーされます。1-指がボタンに触れた直後:UIControlEventTouchDown。これは、長押しの開始をキャプチャします。2&3-ユーザーが指を持ち上げたとき:UIControlEventTouchUpOutsideUIControlEventTouchUpInside。これにより、ユーザーのプレスの終了がキャプチャされます。

注:これは、ジェスチャ認識機能によって提供される追加情報(タッチの場所など)を気にしない場合にうまく機能します。

必要に応じて、中間イベントをさらに追加できます。https://developer.apple.com/documentation/uikit/uicontrolevents?language = objcですべてを参照してください

ストーリーボードの場合: ストーリーボードが選択するデフォルトのイベント(Touch Up Inside)だけでなく、ボタンを3つのイベントに接続します。

ストーリーボードの3つのイベント


0

アプリ用にサブクラス化されたUIButtonがあるので、実装を引き出しました。これをサブクラスに追加することも、UIButtonカテゴリと同じくらい簡単に再コーディングすることもできます。

私の目標は、すべてのコードでView Controllerを乱雑にすることなく、ボタンに長押しを追加することでした。ジェスチャレコグナイザーの状態が始まったときにアクションを呼び出す必要があると判断しました。

わざわざ解決したことがないという警告が出てきます。コードをテストしたがリークはないと思ったので、リークの可能性があると言います。

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

アクションを割り当てるには、この行をviewDidLoadメソッドに追加します。

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

アクションは、すべてのIBActionと同様に定義する必要があります(IBActionなし)。

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

0

何も機能しなかったのでIBAction、長押しコードを書くか、ボタンをクリックstoryboardするController代わりに、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];

}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.