如何在两次点击功能中防止单击功能被调用?

时间:2016-05-15 12:11:19

标签: swift macos gesture

我正在尝试向我的按钮添加自定义行为。如果单击一次 - 将执行一个操作。如果点击两次,则执行另一次。

我看到了such a solution in this answer,我尝试了所有可能的组合:

        clickOnce.shouldBeRequiredToFailByGestureRecognizer(clickTwice)
        clickTwice.shouldBeRequiredToFailByGestureRecognizer(clickOnce)
        clickOnce.shouldRequireFailureOfGestureRecognizer(clickTwice)
        clickTwice.shouldRequireFailureOfGestureRecognizer(clickOnce)
        clickOnce.canPreventGestureRecognizer(clickTwice)
        clickOnce.canBePreventedByGestureRecognizer(clickTwice)
        clickTwice.canPreventGestureRecognizer(clickOnce)
        clickTwice.canBePreventedByGestureRecognizer(clickOnce)

但没有任何对我有用。

这里是完整的代码:

import Cocoa

class ViewController: NSViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.

        let buttonTestOne = NSButton(frame: CGRect(x: 500, y: 500, width: 100, height: 500))

        let clickOnceForTestOne = NSClickGestureRecognizer(target: buttonTestOne, action: #selector(ViewController.clickOneTime(_:)))
        clickOnceForTestOne.numberOfClicksRequired = 1
        buttonTestOne.addGestureRecognizer(clickOnceForTestOne)
        self.view.addSubview(buttonTestOne)

        let arrTestButtons = ["One", "Two", "Three"]

        var x = 0
        var y = 0

        for item in arrTestButtons{
            let buttonNew = NSButton(frame: CGRect(x: x, y: y, width: 100, height: 100))
            x = x + 120
            y = y + 120
            buttonNew.attributedTitle = NSAttributedString(string: item)
            let clickOnce = NSClickGestureRecognizer(target: self, action: #selector(ViewController.clickOneTime(_:)))
            clickOnce.numberOfClicksRequired = 1
            buttonNew.addGestureRecognizer(clickOnce)
            let clickTwice = NSClickGestureRecognizer(target: self, action: #selector(ViewController.clickTwoTimes(_:)))
            clickTwice.numberOfClicksRequired = 2
            buttonNew.addGestureRecognizer(clickTwice)
            clickOnce.shouldBeRequiredToFailByGestureRecognizer(clickTwice)
            clickTwice.shouldBeRequiredToFailByGestureRecognizer(clickOnce)
            clickOnce.shouldRequireFailureOfGestureRecognizer(clickTwice)
            clickTwice.shouldRequireFailureOfGestureRecognizer(clickOnce)
            clickOnce.canPreventGestureRecognizer(clickTwice)
            clickOnce.canBePreventedByGestureRecognizer(clickTwice)
            clickTwice.canPreventGestureRecognizer(clickOnce)
            clickTwice.canBePreventedByGestureRecognizer(clickOnce)

            self.view.addSubview(buttonNew)
        }


    }

    func clickOneTime(g:NSClickGestureRecognizer){
        if g.state == .Ended {
            Swift.print("single click")
        }
    }
    func clickTwoTimes(g: NSClickGestureRecognizer){
        if g.state == .Ended {
            Swift.print("DOUBLE CLICK!")
        }
    }
    override var representedObject: AnyObject? {
        didSet {
        // Update the view, if already loaded.
        }
    }


}

我做错了什么?我认为错误必须非常简单,我要么是从错误的地方打电话,要么就是这样,但我无法理解。

这是日志文件,对于所有组合都是相同的:

点击一次:

single click

正如预期的那样

点击两次:

single click
DOUBLE CLICK!

单击和双击即可开始。

我已阅读文档。我已经尝试了所有组合,因为无法找到解决方案。

我也尝试过日志。所以Swift.print(clickOnce.shouldBeRequiredToFailByGestureRecognizer(clickTwice))和其中一个,但它给了我false

3 个答案:

答案 0 :(得分:0)

试试这个:

let click = NSClickGestureRecognizer(target: self, action: #selector(clicked(_:))
click.numberOfClicksRequired = 2

答案 1 :(得分:0)

我试图自己解决这个问题;事实证明,该解决方案相对简单。

使用手势识别器进行双击(在这里,我已经将它们添加到视图中,但是相同的原理也适用于按钮)

let doubleClickRecognizer = NSClickGestureRecognizer(target: self, action: #selector(ViewController.clickTwice))
doubleClickRecognizer.numberOfClicksRequired = 2
self.view?.addGestureRecognizer(doubleClickRecognizer)

添加

@objc func clickTwice() {
    print("double click")
}

然后处理

override func mouseDown(with event: NSEvent) {
    print("mouse down; once")
}

(或适当的等效值)。

NSGestureRecognizer具有

var delaysPrimaryMouseButtonEvents: Bool

(默认情况下设置为true),因此使用此组合,它会一直等待,直到doubleClickRecognizer处理了双击,然后再上到响应者链,以查看还有谁对鼠标单击感兴趣。

两个手势识别器与在mouseDown中处理单击和双击具有相同的问题:单击首先触发。为了克服这个问题,您需要覆盖

func gestureRecognizer(_ gestureRecognizer: NSGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: NSGestureRecognizer) -> Bool  

这不是您调用的函数,而是您覆盖的委托函数。因此,您将viewController设置为符合NSGestureRecognizerDelegate(这意味着它将接收委托方法);设置singleClickRecognizer.delegate = self(其中self是您的viewController),并实现

func gestureRecognizer(_ gestureRecognizer: NSGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: NSGestureRecognizer) -> Bool {
    if gestureRecognizer == singleClickRecognizer && otherGestureRecognizer == doubleClickRecognizer {
        return true
    }
    return false
    }

这表明您的singleClickRecognizer在执行其选择器之前会等待doubleClickRecognizer失败。

不幸的是,我发现在SpriteKit中,虽然此代码执行了锡上所说的内容(首先处理双击),但它会导致不可接受的延迟,因此我不确定我是否可以推荐它。

答案 2 :(得分:-1)

也许你可以这样试试,其中"按钮"是你的按钮

let doubleTapRecognizer = UITapGestureRecognizer(target: self, action: #selector(ViewController.clickTwoTimes(_:)))
let singleTapRecognizer = UITapGestureRecognizer(target: self, action: #selector(ViewController.clickOneTime(_:)))
singleTapRecognizer.numberOfTapsRequired = 1
doubleTapRecognizer.numberOfTapsRequired = 2
button.addGestureRecognizer(doubleTapRecognizer)
button.addGestureRecognizer(singleTapRecognizer)
singleTapRecognizer.requireGestureRecognizerToFail(doubleTapRecognizer)