如何防止一次单击功能在两次单击功能内被调用? [英] How to prevent one click function to be called within two click function?
问题描述
我正在尝试向按钮添加自定义行为.如果单击一次-将执行一项操作.如果单击两次,则执行另一个.
I am trying to add custom behaviour to my buttons. If clicked once - one action is performed. If clicked twice another one is performed.
我在此答案中看到了这样的解决方案,我尝试了所有可能的组合:
I saw such a solution in this answer and I have tried all possible combinations:
clickOnce.shouldBeRequiredToFailByGestureRecognizer(clickTwice)
clickTwice.shouldBeRequiredToFailByGestureRecognizer(clickOnce)
clickOnce.shouldRequireFailureOfGestureRecognizer(clickTwice)
clickTwice.shouldRequireFailureOfGestureRecognizer(clickOnce)
clickOnce.canPreventGestureRecognizer(clickTwice)
clickOnce.canBePreventedByGestureRecognizer(clickTwice)
clickTwice.canPreventGestureRecognizer(clickOnce)
clickTwice.canBePreventedByGestureRecognizer(clickOnce)
但是对我没有任何帮助.
But nothing worked for me.
这是完整的代码:
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.
}
}
}
我做错了什么?我认为错误一定很简单,我要么是从错误的地方打电话,要么是那样的话,但我听不懂.
What am I doing wrong? I think the mistake must be pretty simple, I am either calling from the wrong place, or somewhat like that, but I can't understand.
这是日志文件,所有组合都相同:
Here is the log file, which is the same for all combinations:
点击一次:
single click
符合预期
单击两次:
single click
DOUBLE CLICK!
同时单击和双击.
我已经阅读了文档.我已经尝试了所有组合,因为找不到解决方案.
I have read the documentation. And I've tried all the combinations, because couldn't find a solution.
我也尝试过使用日志.所以Swift.print(clickOnce.shouldBeRequiredToFailByGestureRecognizer(clickTwice))
和其中之一,但是它给了我false
.
I have also tried with the logs. So Swift.print(clickOnce.shouldBeRequiredToFailByGestureRecognizer(clickTwice))
and one of these, but it gives me false
.
推荐答案
我试图自己解决这个问题;事实证明,该解决方案相对简单.
I was trying to solve this myself; it turns out that the solution is relatively straightforward.
使用手势识别器进行双击(在这里,我已经将它们添加到视图中,但是相同的原理也适用于按钮)
Use a gesture recogniser for the double-click (here, I've added them to the view, but the same principle should work for buttons)
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")
}
(或适当的等效值).
(or appropriate equivalent).
NSGestureRecognizer具有
NSGestureRecognizer has
var delaysPrimaryMouseButtonEvents: Bool
(默认情况下设置为true),因此使用此组合,它会一直等待,直到doubleClickRecognizer处理了双击,然后再上到响应者链,以查看还有谁对鼠标单击感兴趣.
which by default is set to true, so with this combination, it waits until the doubleClickRecognizer has handled the double-click before going up the responder chain to see who else is interested in a mouseclick.
两个手势识别器与在mouseDown中处理单击和双击具有相同的问题:单击首先触发.为了克服这个问题,您需要覆盖
Two gesture recognisers have the same problem as handling single and double clicks in mouseDown: the single click fires first. In order to overcome this, you need to override
func gestureRecognizer(_ gestureRecognizer: NSGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: NSGestureRecognizer) -> Bool
这不是您调用的函数,而是您覆盖的委托函数.因此,您将viewController设置为符合NSGestureRecognizerDelegate(这意味着它将接收委托方法);设置singleClickRecognizer.delegate = self(其中self是您的viewController),并实现
This is not a function you call, it's a delegate function that you override. So you set your viewController to conform to NSGestureRecognizerDelegate (which means it will receive delegate methods); set singleClickRecognizer.delegate = self (where self is your viewController), and implement
func gestureRecognizer(_ gestureRecognizer: NSGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: NSGestureRecognizer) -> Bool {
if gestureRecognizer == singleClickRecognizer && otherGestureRecognizer == doubleClickRecognizer {
return true
}
return false
}
指出您的singleClickRecognizer在执行其选择器之前,等待doubleClickRecognizer失败.
which states that your singleClickRecognizer waits for the doubleClickRecognizer to fail before executing its selector.
不幸的是,我发现在SpriteKit中,虽然这段代码确实做到了(首先处理双击),但它会导致不可接受的延迟,所以我不确定我是否可以推荐它.
Unfortunately, I have found that in SpriteKit, while this code does what it says on the tin (process a double-click first), it leads to unacceptable delays, so I'm not sure I can recommend it.
这篇关于如何防止一次单击功能在两次单击功能内被调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!