Cocoa 提供了许多有用的方法来检测手势和鼠标点击的开始和结束状态。对于鼠标点击,我们可以轻松地覆盖mouseDown:
和mouseUp:
方法。然而,我们似乎没有办法对鼠标滚动事件做同样的事情——我们只提供了scrollWheel:
在滚动发生时激活的方法。
我试过beginGestureWithEvent:
了,但它只响应触摸事件。
有没有办法检测 Cocoa 中鼠标滚动的开始和结束状态?
Cocoa 提供了许多有用的方法来检测手势和鼠标点击的开始和结束状态。对于鼠标点击,我们可以轻松地覆盖mouseDown:
和mouseUp:
方法。然而,我们似乎没有办法对鼠标滚动事件做同样的事情——我们只提供了scrollWheel:
在滚动发生时激活的方法。
我试过beginGestureWithEvent:
了,但它只响应触摸事件。
有没有办法检测 Cocoa 中鼠标滚动的开始和结束状态?
我发现检测 onScrollWheelDown 和 onScrollWheelUp 的最佳方法是使用event.phase == MayBegin
onDownevent.phase == Cancelled
和event.phase == Ended
onUp。这甚至在您的手势离开触控板时也有效,并且也适用于 MagicMouse。稍后我将测试 MagicMouse。
您可以在此处阅读有关我如何得出此结论的更深入分析:http: //stylekit.org/blog/2016/02/28/Scroll-wheel/
正如我所见,没有这么简单的解决方案。但你仍然可以这样做。
最明显的是使用计时器来检查轮子上次滚动的时间。为此,我更喜欢使用轻量级 GCD 计时器(它们也是支持 ARC 的对象,而不是存储strong
目标引用的 NSTimer)。
- (void) scrollWheel:(NSEvent *)event
{
_lastStamp = mach_absolute_time(); // get current timestamp
if (!_running)
{
if (!_timer)
[self createTimerSource];
if (!_running)
dispatch_resume(_timer);
_running = YES;
}
}
- (void)createTimerSource
{
NSTimeInterval timeout = ...;
_timer=dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _timerQueue);
dispatch_source_set_timer(_timer, DISPATCH_TIME_NOW, timeout * NSEC_PER_SEC, 0);
// set the event handler
dispatch_source_set_event_handler(_timer, ^{
uint64_t stamp = mach_absolute_time(); // current stamp
if (stamp - _lastStamp > some_tolerance_value)
{
// wheel did end scroll
if (_running)
dispatch_source_cancel(_timer);
_running = NO;
}
});
}
查看文章以了解有关Dispatch Sources的更多信息。