web-dev-qa-db-ja.com

iOSはUIViewのタップダウンとタッチアップを検出します

UIViewがタッチダウンされ、UIViewがタップされていることを検出する方法を決定する問題で立ち往生しています。タッチダウンしたら、UIViewの背景色を変更します。触れられたら、UIViewに特定のタスクを実行させたいです。この問題を解決する方法を知りたいです。

-(void)viewDidLoad
{        
    UITapGestureRecognizer *dismissGestureRecognition = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDismissDoubleTap:)];
    dismissGestureRecognition.numberOfTapsRequired = 1;
    [sectionDismissDoubleView addGestureRecognizer:dismissGestureRecognition];

    UITapGestureRecognizer *dismissGestureDownRecognition = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissGestureDownRecognition:)];
    dismissGestureRecognition.numberOfTouchesRequired = 1;
    [sectionDismissDoubleView addGestureRecognizer:dismissGestureDownRecognition];
}

- (void)handleDismissDoubleTap:(UIGestureRecognizer*)tap {
    SettingsDismissDoubleViewController *settingsDouble = [[SettingsDismissDoubleViewController alloc] initWithNibName:@"SettingsDismissDoubleViewController" bundle:nil];
    [self.navigationController pushViewController:settingsDouble animated:YES];
}

- (void)dismissGestureDownRecognition:(UIGestureRecognizer*)tap {
    NSLog(@"Down");
}
34
user288231

Gesture Recognizerは、おそらくあなたが望むものに対してはやりすぎです。おそらく、-touchesBegan:withEvent:-touchesEnded:withEvent:の組み合わせを使用するだけです。

これには欠陥がありますが、それはあなたに何をしたいのかというアイデアを与えるはずです。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    self.touchDown = YES;
    self.backgroundColor = [UIColor redColor];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    // Triggered when touch is released
    if (self.isTouchDown) {
        self.backgroundColor = [UIColor whiteColor];
        self.touchDown = NO;
    }
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    // Triggered if touch leaves view
    if (self.isTouchDown) {
        self.backgroundColor = [UIColor whiteColor];
        self.touchDown = NO;
    }
}

このコードは、作成したUIViewのカスタムサブクラスに配置する必要があります。次に、UIViewの代わりにこのカスタムビュータイプを使用すると、タッチ処理が行われます。

41
Holly

enter image description here

このメソッドはサブクラス化を必要としません。 UILongPressGestureRecognizerをビューに追加し、minimumPressDurationをゼロに設定するだけです。次に、ジェスチャーイベントが呼び出されたときの状態を確認して、タッチイベントが開始しているか終了しているかを確認します。

上記の画像例のプロジェクトコード全体を次に示します。

import UIKit
class ViewController: UIViewController {

    @IBOutlet weak var myView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Add "long" press gesture recognizer
        let tap = UILongPressGestureRecognizer(target: self, action: #selector(tapHandler))
        tap.minimumPressDuration = 0
        myView.addGestureRecognizer(tap)
    }

    // called by gesture recognizer
    func tapHandler(gesture: UITapGestureRecognizer) {

        // handle touch down and touch up events separately
        if gesture.state == .Began {
            myView.backgroundColor = UIColor.darkGrayColor()
        } else if  gesture.state == .Ended {
            myView.backgroundColor = UIColor.lightGrayColor()
        }
    }
}

この回答 のアイデアに感謝します。

47
Suragch

すべてのUIControlサブクラス(UIButtonなど)で、これを使用してUIControlEventの特定のセットをサブスクライブできます。

addTarget:action:forControlEvents

UIControlEventTouchDownの適切なセレクターとUIControlEventTouchUpInsideイベントの別のターゲット/セレクターでターゲットを追加する必要があります。

IControlリファレンス

6
opedge

Holly's answer のおかげで、ButtonViewコンビニエンスクラスを作成しました。

編集: answer のとおり、UILongPressGestureRecognizerは非常に高速に反応するため、クラスを更新しました。

使用法:

let btn = ButtonView()
btn.onNormal = { btn.backgroundColor = .clearColor() }
btn.onPressed = { btn.backgroundColor = .blueColor() }
btn.onReleased = yourAction // Function to be called

クラス:

/** View that can be pressed like a button */

import UIKit

class ButtonView : UIView {

    /* Called when the view goes to normal state (set desired appearance) */
    var onNormal = {}
    /* Called when the view goes to pressed state (set desired appearance) */
    var onPressed = {}
    /* Called when the view is released (perform desired action) */
    var onReleased = {}

    override init(frame: CGRect)
    {
        super.init(frame: frame)

        let recognizer = UILongPressGestureRecognizer(target: self, action: Selector("touched:"))
        recognizer.delegate = self
        recognizer.minimumPressDuration = 0.0
        addGestureRecognizer(recognizer)
        userInteractionEnabled = true

        onNormal()
    }

    func touched(sender: UILongPressGestureRecognizer)
    {
        if sender.state == .Began {
            onPressed(self)
        } else if sender.state == .Ended {
            onNormal(self)
            onReleased()
        }
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
2
Ferran Maylinch

まず、セレクターによってhandleDismissDoubleTap:、ダブルタップを解除するのを探していると思います。これを実現するには、次のことを行う必要があります。dismissGestureRecognition.numberOfTapsRequired = 2;

第二に、タッチダウンが長時間のタップ(または「タップアンドホールド」)のようなジェスチャーを意味する場合、UILongPressGestureRecognizerの代わりにUITapGestureRecognizerを使用する必要があります。

1
Bell App Lab