Mac Cocoa: как отличить событие NSScrollWheel от мыши или трекпада?

В моем приложении я хочу, чтобы прокрутка выполнялась только с помощью колеса прокрутки с помощью мыши, а не с помощью жеста двумя пальцами на трекпаде. По сути, я пытаюсь определить, генерируется ли scrollWheelEvent с помощью мыши или трекпада, внутри - (void) scrollWheel: (NSEvent *) методEvent. Из того, что я знаю до сих пор, кажется, что нет простого способа добиться этого.

Я попробовал обойтись, установив для логической переменной значение true и false внутри - (void) beginGestureWithEvent: (NSEvent *) event; и - (void) endGestureWithEvent: (NSEvent *) событие; Но это не решение, потому что метод scrollWheel: вызывается несколько раз после вызова метода endGestureWithEvent :.

Вот мой код:

    $BOOL fromTrackPad = NO;

    -(void)beginGestureWithEvent:(NSEvent *)event;
    {
        fromTrackPad = YES;    
    }

    -(void) endGestureWithEvent:(NSEvent *)event;
    {
        fromTrackPad = NO;    
    }

    - (void)scrollWheel:(NSEvent *)theEvent
    {
       if(!fromTrackPad)
       {
          //then do scrolling
       }
       else 
       {
         //then don't scroll
       }
    }

Я знаю, что это нестандартно, но это мое требование. Кто-нибудь знает, как это сделать ?? Спасибо!


person AProgrammer    schedule 10.12.2012    source источник
comment
Это звучит как что-то гораздо более низкое. Что, если пользователь прокручивает трекпадом и мышью одновременно?   -  person TheAmateurProgrammer    schedule 11.12.2012
comment
Здравствуйте, TheAmateurProgrammer, как я уже упоминал, вопрос, который я разместил, не является чем-то стандартным. Я ищу способ реализовать эту функцию, и любая идея приветствуется!   -  person AProgrammer    schedule 11.12.2012


Ответы (4)


-[NSEvent momentumPhase] - это решение. Таким образом, события, сгенерированные трекпадом между событиями beginGesture и endGesture, возвращают значение, отличное от NSEventPhaseNone для -[NSEvent phase], а события трекпада, сгенерированные после события endGesture, возвращают значение, отличное от NSEventPhaseNone для -[NSEvent momentumPhase]. Код ниже,

 - (void)scrollWheel:(NSEvent *)theEvent
    {
       if(([theEvent momentumPhase] != NSEventPhaseNone) || [theEvent phase] != NSEventPhaseNone))
       {
          //theEvent is from trackpad           
       }
       else 
       {
         //theEvent is from mouse
       }
    }
person AProgrammer    schedule 20.12.2012
comment
Неправильный!!! При таком подходе прокрутка с помощью мыши Apple Magic будет определяться как трекпад. - person Yoav; 10.11.2013
comment
Это не так. Поверхность отслеживания Magic Mouse считается трекпадом в OS X. Кроме того, сдерживайте восклицательные знаки. - person Ed Ropple; 10.12.2013
comment
Ваш код может работать, но я лично не хотел бы его использовать. Код не проверяет, является ли устройство сенсорной панелью или нет, он проверяет случайные атрибуты, которые в настоящее время имеют только сенсорные панели. Это затрудняет чтение и делает возможным взлом в будущем. Пробовал ли OP этот подход: stackoverflow.com/questions/14461529/nsevent -и-волшебная-мышь? Если предположить, что это работает, это лучше. - person original_username; 26.11.2015

Вы можете использовать [event hasPreciseScrollingDeltas], чтобы различать. Он был добавлен в OS X Lion. Он различает события прокрутки строки (колеса мыши) и прокрутки пикселей (трекпады, волшебная мышь).

person Kelvin M    schedule 02.11.2013
comment
Может быть, я привередливый, но я думаю, что у этого ответа та же проблема, что и у @ AProgrammer. Поскольку он не делает в точности то, что написано на банке, он может сломаться в будущем, и человеку будет сложно интерпретировать его. - person original_username; 26.11.2015
comment
В вашем ответе есть опечатка: Неверно: [событие hasPreciciseScrollingDeltas] Правильно: [событие hasPreciseScrollingDeltas] - person Antoine Rosset; 09.09.2016

Мой ответ на Swift, но для Objective C логика такая же:

override func scrollWheel(with event: NSEvent) {
  if event.subtype == .mouseEvent {
    // mouse
  } else {
    // trackpad
  }
}
person Igor    schedule 12.03.2017

Ответ @AProgrammer может быть недоступен. Потому что событие scrollwheel, генерируемое волшебной мышью, имеет значения фазы: началось, изменилось и закончилось. И событие scrollwheel, генерируемое могучей мышью, не имеет значения ни для фазы, ни для фазы импульса. Таким образом, с помощью этого метода можно отличить только могучую мышь от волшебной мыши и трекпада.

person holybiner    schedule 18.10.2016
comment
Но как отличить внутри scrollWheel трекпад от волшебной мыши? - person Tom; 19.10.2018