检测Cocoa中Scroll Wheel事件的开始和结束状态

时间:2015-04-01 01:17:30

标签: cocoa event-handling scrollwheel

Cocoa提供了许多有用的方法来检测手势和鼠标点击的开始结束状态。对于鼠标点击,我们可以轻松覆盖mouseDown:mouseUp:方法。但是,我们似乎没有办法为鼠标滚动事件做同样的事情 - 我们只提供了scrollWheel:方法,该方法在滚动时被激活。

我尝试了beginGestureWithEvent:,但它只响应触摸事件。

有没有办法在Cocoa中检测鼠标滚动的开始和结束状态?

2 个答案:

答案 0 :(得分:2)

我发现检测onScrollWheelDown和onScrollWheelUp的最佳方法是将event.phase == MayBegin用于onDown event.phase == Cancelled,将event.phase == Ended用于onUp。当你的手势离开触控板并且也适用于MagicMouse时,这甚至可以正常工作。我稍后会测试MagicMouse。

您可以在此深入分析我如何得出这个结论:http://stylekit.org/blog/2016/02/28/Scroll-wheel/

答案 1 :(得分:1)

我认为没有这么简单的解决方案。 但你仍然可以做到这一点。

最明显的是使用计时器检查车轮上次滚动的时间。我更喜欢使用轻量级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的更多信息。