Help us understand the problem. What is going on with this article?

【iOS】UITapGestureの共存

More than 3 years have passed since last update.

iOS その3 Advent Calendar

5日目を書かせて頂きます!

を書かせてもらっています!

では本題に入ります。

1つのViewでシングルタップとダブルタップを検知したい

ってことが前にありました。

普通にかくと以下のようになると思います。

ViewController.swift
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        let singleTapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.handleSingleTapGesture(_:)))
        singleTapGesture.numberOfTapsRequired = 1
        singleTapGesture.numberOfTouchesRequired = 1
        view.addGestureRecognizer(singleTapGesture)

        let doubleTapGesture = UITapGestureRecognizer(target: self , action: #selector(ViewController.handleDoubleTapGesture(_:)))
        doubleTapGesture.numberOfTapsRequired = 2
        doubleTapGesture.numberOfTouchesRequired = 1
        view.addGestureRecognizer(doubleTapGesture)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // single tap
    @IBAction func handleSingleTapGesture(_ gesture: UITapGestureRecognizer) {
        print("single tap")
    }

    @IBAction func handleDoubleTapGesture(_ gesture: UITapGestureRecognizer) {
        print("double tap")
    }

}

ただ上記のように実装すると以下のようにログが流れます。

12月-03-2016 23-06-52.gif

わかりづらいかもですが、doubleTapGestureのイベントの前にも必ずsingleTapGestureの処理が入っていることです。

望んでいるのはdoubleTapGestureが動作するときはsingleTapGestureは反応して欲しくないのです。

ということで手を加える

以下のように実装すると僕が望んだ通りの処理になりました。

ViewController.swift
class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        let singleTapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.handleSingleTapGesture(_:)))
        singleTapGesture.numberOfTapsRequired = 1
        singleTapGesture.numberOfTouchesRequired = 1
        view.addGestureRecognizer(singleTapGesture)

        let doubleTapGesture = UITapGestureRecognizer(target: self , action: #selector(ViewController.handleDoubleTapGesture(_:)))
        doubleTapGesture.numberOfTapsRequired = 2
        doubleTapGesture.numberOfTouchesRequired = 1
        view.addGestureRecognizer(doubleTapGesture)

        // こいつを加える!!
        singleTapGesture.require(toFail: doubleTapGesture)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // single tap
    @IBAction func handleSingleTapGesture(_ gesture: UITapGestureRecognizer) {
        print("single tap")
    }

    @IBAction func handleDoubleTapGesture(_ gesture: UITapGestureRecognizer) {
        print("double tap")
    }

}

すると以下のようになります。

12月-03-2016 23-11-46.gif

ログが重複しなくりました!

懸念点

今回加えたUIGestureRecognizerfunc require(toFail otherGestureRecognizer: UIGestureRecognizer)は以下のように説明がありました。

Creates a dependency relationship between the receiver and another gesture recognizer when the objects are created.

require(toFail:) - UIGestureRecognizer | Apple Developer Documentationより

最近とても優秀なGoogle翻訳にかけると

受信者と別のジェスチャ認識プログラムがオブジェクトの作成時に依存関係を作成します。

となりました。

簡単にソースコードの意味で説明すると

singleTapGesture.require(toFail: doubleTapGesture)doubleTapGestureFailしたらsingleTapGestureが実行されるという依存関係を結んだということになりますかね...。

最近betaツールでスクショを送れたりページにコメントできたりというのがあって、3本指でタップしたらなどのイベントを生成していると思いますが、かぶることもあり得るのでここら辺上記のメソッドで依存関係を一番最後に回すようなことを考えたら楽になりそうだなって思ったり...。

最後に

GIPHY CAPTUREとっても便利でした。

以上です。

ryokosuge
金髪iOS エンジニア なんか色々やってます
https://ryokosuge.github.io/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした