MAC开发之点击任意位置触发事件(监听全局事件)

       在MAC开发中,我们时常会有一些要监听鼠标或者键盘全局事件的需求,比如说如图一:当我鼠标点击程序其他位置的时候,我需要把在线状态这个小窗口给关掉,但是又不能影响事件的传递。此时我们就需要通过全局事件的锚点来实现(其他编程语言中也叫钩子事件):

MAC开发之点击任意位置触发事件(监听全局事件)_第1张图片
图一

还是先上代码:

```

self.mEventMonitor= [NSEvent addLocalMonitorForEventsMatchingMask:

NSLeftMouseDownMask|NSLeftMouseDraggedMask|NSLeftMouseUpMask

handler:^NSEvent*_Nullable(NSEvent* event) {

//获取触发事件坐标

NSPoint p = [event locationInWindow];

//判断坐标是否处于保护区内

NSPoint newP = [weakself.mBox_state convertPoint:p fromView:nil];

if(!CGRectContainsPoint(weakself.mBox_state.bounds, newP)) {

weakself.mBox_state.hidden = YES;

weakself.mBox_state=nil;

}

//把注册的锚点事件移除掉

[NSEvent removeMonitor:weakself.mEventMonitor];

weakself.mEventMonitor=nil;

//返回事件,让事件继续传递

returnevent;

}];

```

       代码很简单,原理更简单,就是在系统在传递事件的过程中,插入了一个回调,而这个回调是一个Block,而我们需要做的就是通过addLocalMonitorForEventsMatchingMask函数给回调Block赋上值。触发Block回调的条件就是 addLocalMonitorForEventsMatchingMask 函数的第一个参数,是一个位枚举,上面代码给了三个触发条件,分别是NSLeftMouseDownMask、NSLeftMouseDraggedMask、NSLeftMouseUpMask。

        上面代码之所以做一次判断事件坐标是否在保护区内,是不想在点击状态窗口的时候把窗口给关掉,因为我还要做改变在线状态的点击事件呢,你把窗口给我关掉了,控件给释放了,我还怎么继续?

       下面,来看下苹果都给了哪些可以触发回调Block的条件:

```

typedefNS_OPTIONS(unsignedlonglong, NSEventMask) {/* masks for the types of events */

NSEventMaskLeftMouseDown=1<

NSEventMaskLeftMouseUp=1<

NSEventMaskRightMouseDown=1<

NSEventMaskRightMouseUp=1<

NSEventMaskMouseMoved=1<

NSEventMaskLeftMouseDragged=1<

NSEventMaskRightMouseDragged=1<

NSEventMaskMouseEntered=1<

NSEventMaskMouseExited=1<

NSEventMaskKeyDown=1<

NSEventMaskKeyUp=1<

NSEventMaskFlagsChanged=1<

NSEventMaskAppKitDefined=1<

NSEventMaskSystemDefined=1<

NSEventMaskApplicationDefined=1<

NSEventMaskPeriodic=1<

NSEventMaskCursorUpdate=1<

NSEventMaskScrollWheel=1<

NSEventMaskTabletPoint=1<

NSEventMaskTabletProximity=1<

NSEventMaskOtherMouseDown=1<

NSEventMaskOtherMouseUp=1<

NSEventMaskOtherMouseDragged=1<

/* The following event masks are available on some hardware on 10.5.2 and later */

NSEventMaskGestureNS_ENUM_AVAILABLE_MAC(10_5)=1<

NSEventMaskMagnifyNS_ENUM_AVAILABLE_MAC(10_5)=1<

NSEventMaskSwipeNS_ENUM_AVAILABLE_MAC(10_5)=1U <

NSEventMaskRotateNS_ENUM_AVAILABLE_MAC(10_5)=1<

NSEventMaskBeginGestureNS_ENUM_AVAILABLE_MAC(10_5)=1<

NSEventMaskEndGestureNS_ENUM_AVAILABLE_MAC(10_5)=1<

#if __LP64__

/* Note: You can only use these event masks on 64 bit. In other words, you cannot setup a local, nor global, event monitor for these event types on 32 bit. Also, you cannot search the event queue for them (nextEventMatchingMask:...) on 32 bit.

*/

NSEventMaskSmartMagnifyNS_ENUM_AVAILABLE_MAC(10_8) =1ULL <

NSEventMaskPressureNS_ENUM_AVAILABLE_MAC(10_10_3) =1ULL <

NSEventMaskDirectTouchNS_ENUM_AVAILABLE_MAC(10_12_1) =1ULL <

#endif

NSEventMaskAny=NSUIntegerMax,

};

```

      啧啧,还真不少,算了,就不翻译了,只是为了大家看着方便才贴出来这儿的......

你可能感兴趣的:(MAC开发之点击任意位置触发事件(监听全局事件))