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 *)touches withEvent:(nullable UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(nullable UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(nullable UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(nullable UIEvent *)event;
根据方法名可以知道各自的调用时机。如果我们想画图,可以使用上面的函数,至于单击、双击、长按等手势还是使用UIGestureRecognizer
更加方便。使用UIGestureRecognizer
需要注意它会截取触摸事件,可能导致某些事件无法触发,需要要设置delaysTouchesBegan
为 ##NO## 来调用hitTest
。
按键命令根据UIKeyCommand
的文档可以知道是和实体键盘相关的,而输入视图根据UIInputViewController
的文档可以知道是自定义键盘有关,也就是iOS 8添加的第三方键盘。
如果想深入了解iOS的事件,还需要了解一下UIView
的hitTest
、pointInside
方法以及NSRunLoop
。
PS.多读源码、注释以及文档还是很有好处的