UIResponder是響應各種事件的,之前說了UIView是UIResponder的子類,UIViewController、UIWindow、UIApplication也是UIResponder的之類。
目前iOS中的事件主要有4種,可以在UIEvent.h
中查看。
typedef NS_ENUM(NSInteger, UIEventType) {
UIEventTypeTouches,
UIEventTypeMotion,
UIEventTypeRemoteControl,
UIEventTypePresses NS_ENUM_AVAILABLE_IOS(9_0),
};
一般常用的touch、motion、press,其中press是新增的3D touch,iOS 9添加的。
UIResponder根據UIResponder.h
大體上可以分成四部分:
1.響應鏈
2.事件
3.按鍵命令(UIResponderKeyCommands
)
4.輸入視圖(UIResponderInputViewAdditions
)
響應鏈其實很好理解,可以認為是一個responder不處理某個事件,將這個事件轉交nextResponder
處理。順序一般是:
子視圖->父視圖->視圖控制器->父視圖->視圖控制器->UIWindow->UIApplication。
一般我們使用觸摸事件,常用的方法如下:
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
根據方法名可以知道各自的調用時機。如果我們想畫圖,可以使用上面的函數,至于單擊、雙擊、長按等手勢還是使用UIGestureRecognizer
更加方便。使用UIGestureRecognizer
需要注意它會截取觸摸事件,可能導致某些事件無法觸發,需要要設置delaysTouchesBegan
為 ##NO## 來調用hitTest
。
按鍵命令根據UIKeyCommand
的文檔可以知道是和實體鍵盤相關的,而輸入視圖根據UIInputViewController
的文檔可以知道是自定義鍵盤有關,也就是iOS 8添加的第三方鍵盤。
如果想深入了解iOS的事件,還需要了解一下UIView
的hitTest
、pointInside
方法以及NSRunLoop
。
PS.多讀源碼、注釋以及文檔還是很有好處的