我有一个自定义的 NSView
(它是众多 NSView 之一,它们都位于 NSCollectionView
内 - 我认为这不相关,但谁知道呢)。当我单击 View 时,我希望它更改其选择状态(并相应地重新绘制自身);当我双击 View 时,我希望它为刚刚双击的对象弹出一个更大的预览窗口。
我的第一个看起来像这样:
- (void)mouseUp: (NSEvent *)theEvent {
if ([theEvent clickCount] == 1) [model setIsSelected: ![model isSelected]];
else if ([theEvent clickCount] == 2) if ([model hasBeenDownloaded]) [mainWindowController showPreviewWindowForPicture:model];
}
大部分工作得很好。不过,当我双击 View 时,选择状态会发生变化,并且窗口会弹出。这不正是我想要的。
看来我有两个选择。我可以在响应双击时恢复选择状态(撤消错误的单击),也可以使用某种 NSTimer
解决方案在响应单击之前构建延迟。换句话说,我可以确保在更改选择状态之前不会出现第二次单击。
这看起来更优雅,所以这是我一开始采取的方法。我从谷歌找到的唯一真正的指导是在一个名称中带有连字符的未命名网站上。这种方法大多有效,但有一个很大的警告。
悬而未决的问题是“我的 NSTimer
应该等待多长时间?”。该未命名网站建议使用 Carbon 函数 GetDblTime()
。除了在 64 位应用程序中无法使用之外,我能找到的唯一文档表明它正在返回时钟滴答声。我不知道如何将这些转换为 NSTimer 的秒数。
那么这里的“正确”答案是什么?摸索着GetDblTime()
?双击“撤消”选择?我无法弄清楚 Cocoa 惯用的方法。
最佳答案
延迟选择状态的更改是(据我所知)执行此操作的推荐方法。
实现起来非常简单:
- (void)mouseUp:(NSEvent *)theEvent
{
if([theEvent clickCount] == 1) {
[model performSelector:@selector(toggleSelectedState) afterDelay:[NSEvent doubleClickInterval]];
}
else if([theEvent clickCount] == 2)
{
if([model hasBeenDownloaded])
{
[NSRunLoop cancelPreviousPerformRequestsWithTarget: model];
[mainWindowController showPreviewWindowForPicture:model];
}
}
}
(请注意,在 10.6 中,双击间隔可作为 NSEvent
上的类方法访问)
关于cocoa - Mac 上的 Cocoa 中区分单击和双击,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1664920/