1. 事件的傳遞
先要介紹一下
事件傳遞
, 簡單的就是 手機端捕捉到一個事件 =》 傳遞給App =》 Window =》 Controller =》 View =》 子視圖 ; 一般通過hitTest:withEvent
和pointInside:withEvent
來查找,這個過程比較簡單吏垮,網上有很多怖糊;但是網上對于事件的響應的介紹確很少胁勺;
2. 事件的響應
就是 通過
touchesBegan:withEvent:
,touchesMoved:withEvent
,touchesCancelled:withEvent
,touchesEnded:withEvent
來進行事件的接收和處理锅锨;
3. 通過一個簡單的例子 來看看
- 定義 一個 子視圖 MyView圈驼;
- 父視圖 Controller的 self.view 來承載MyView
@implementation MyView
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSLog(@"MyView touchesBegan");
// 觸發(fā) parentView的 touchBegan
[super touchesBegan:touches withEvent:event];
NSLog(@"MyView touchesBegan--2");
}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSLog(@"MyView touchesMoved");
[super touchesMoved:touches withEvent:event];
}
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSLog(@"MyView touchesCancelled");
[super touchesCancelled:touches withEvent:event];
NSLog(@"MyView touchesCancelled-2");
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSLog(@"MyView touchesEnded");
[super touchesEnded:touches withEvent:event];
NSLog(@"MyView touchesEnded——2");
}
@end
并且在 Controller 也添加
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSLog(@"self.view touchesBegan");
[super touchesBegan:touches withEvent:event];
}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSLog(@"self.view touchesMoved");
[super touchesMoved:touches withEvent:event];
}
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSLog(@"self.view touchesCancelled");
[super touchesCancelled:touches withEvent:event];
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSLog(@"self.view touchesEnded");
[super touchesEnded:touches withEvent:event];
}
通過點擊 MyView 我大概得出一些簡單的結論
3.1 正常的觸發(fā)
說明先觸發(fā) 最上面的 子視圖 touchesBegan =》 parentView的 touchBegan =》 子視圖 touchesBegan 結束捕儒;
MyView touchesBegan
self.view touchesBegan
MyView touchesBegan--2
MyView touchesEnded
self.view touchesEnded
MyView touchesEnded——2
3.2 注釋掉 MyView 里面的 [super touchesBegan:touches withEvent:event]; 和 [super touchesEnded:touches withEvent:event];
父類的 touchBegan 和 touchesEnd 沒有調用
MyView touchesBegan
MyView touchesBegan--2
MyView touchesEnded
MyView touchesEnded——2
3.3 MyView 中 添加手勢
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapClick)];
[self addGestureRecognizer:tap];
}
return self;
}
- (void)tapClick {
NSLog(@"MyView tapClick");
}
會直接
touchesCancelled
掉,然后去執(zhí)行手勢了龙致;在 https://developer.apple.com/documentation/uikit/uigesturerecognizer 中介紹了蛀缝,手勢 的優(yōu)先級 要比 UIRespons 要高,所以當遇到手勢目代,UIResponse 直接被canceled屈梁;
A window delivers touch events to a gesture recognizer before it delivers them to the hit-tested view attached to the gesture recognizer. Generally, if a gesture recognizer analyzes the stream of touches in a multi-touch sequence and doesn’t recognize its gesture, the view receives the full complement of touches. If a gesture recognizer recognizes its gesture, the remaining touches for the view are cancelled
MyView touchesBegan
self.view touchesBegan
MyView touchesBegan--2
// 手勢響應
MyView tapClick
// 會進入cancelled的響應
MyView touchesCancelled
self.view touchesCancelled
MyView touchesCancelled-2