? ? ? ?在MAC開發(fā)中,我們時常會有一些要監(jiān)聽鼠標(biāo)或者鍵盤全局事件的需求,比如說如圖一:當(dāng)我鼠標(biāo)點(diǎn)擊程序其他位置的時候,我需要把在線狀態(tài)這個小窗口給關(guān)掉,但是又不能影響事件的傳遞。此時我們就需要通過全局事件的錨點(diǎn)來實(shí)現(xiàn)(其他編程語言中也叫鉤子事件):
還是先上代碼:
```
self.mEventMonitor= [NSEvent addLocalMonitorForEventsMatchingMask:
NSLeftMouseDownMask|NSLeftMouseDraggedMask|NSLeftMouseUpMask
handler:^NSEvent*_Nullable(NSEvent* event) {
//獲取觸發(fā)事件坐標(biāo)
NSPoint p = [event locationInWindow];
//判斷坐標(biāo)是否處于保護(hù)區(qū)內(nèi)
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;
}
//把注冊的錨點(diǎn)事件移除掉
[NSEvent removeMonitor:weakself.mEventMonitor];
weakself.mEventMonitor=nil;
//返回事件,讓事件繼續(xù)傳遞
returnevent;
}];
```
? ? ? ?代碼很簡單,原理更簡單,就是在系統(tǒng)在傳遞事件的過程中,插入了一個回調(diào),而這個回調(diào)是一個Block,而我們需要做的就是通過addLocalMonitorForEventsMatchingMask函數(shù)給回調(diào)Block賦上值。觸發(fā)Block回調(diào)的條件就是 addLocalMonitorForEventsMatchingMask 函數(shù)的第一個參數(shù),是一個位枚舉,上面代碼給了三個觸發(fā)條件,分別是NSLeftMouseDownMask、NSLeftMouseDraggedMask、NSLeftMouseUpMask。
? ? ? ? 上面代碼之所以做一次判斷事件坐標(biāo)是否在保護(hù)區(qū)內(nèi),是不想在點(diǎn)擊狀態(tài)窗口的時候把窗口給關(guān)掉,因?yàn)槲疫€要做改變在線狀態(tài)的點(diǎn)擊事件呢,你把窗口給我關(guān)掉了,控件給釋放了,我還怎么繼續(xù)?
? ? ? ?下面,來看下蘋果都給了哪些可以觸發(fā)回調(diào)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,
};
```
? ? ? 嘖嘖,還真不少,算了,就不翻譯了,只是為了大家看著方便才貼出來這兒的......