【问题标题】:How to prevent one click function to be called within two click function?如何防止在两次点击函数中调用一次点击函数?
【发布时间】:2016-05-15 12:11:19
【问题描述】:

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

我看到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

【问题讨论】:

  • 您不能简单地将各种代码行混在一起并期望代码按预期运行。阅读您调用的每个方法的文档,并尝试找出哪个手势识别器可以以何种方式影响另一个。
  • 您提到的示例适用于 iOS,而不是 OS X,因此用鼠标单击两次可能与用手指在设备上双击具有相同的效果。此外,“没有什么对我有用”没有说明它是如何不起作用的,你应该在你的问题中解释这一点。
  • @luk2302 我没有将它们全部混合,我只是尝试了所有组合并发布了类似的代码
  • 我怀疑你尝试了所有这些,有 2^8,也就是 256 种组合。请接受我的建议并阅读文档。
  • @luk2302 我已经阅读了文档,好的,我还没有尝试过所有 256 个组合,但是我尝试了文档中似乎最合乎逻辑的方法。一个接一个,一气呵成。至少如果有一种组合可以发挥作用,它就会出现。

标签: swift macos gesture


【解决方案1】:

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

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

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】:

    试试这个:

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

    【讨论】:

      【解决方案3】:

      也许你可以这样尝试,“按钮”是你的按钮

      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)
      

      【讨论】:

      • 这是 iOS,我正在尝试为 OS X 寻找解决方案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多