iOS 中的事件
- 触摸事件
- 加速计事件
- 远程控制事件
iOS 中的触摸事件
1、触摸事件发生,操作系统iOS会将此类事件包装成UITouch和UIEvent对象,发送给当前运行的应用程序
2、在应用程序内部,AppDelegate开始逐级往下寻找能够响应该事件的对象,顺序是AppDelegate -> UIApplication -> UIWindow -> UIViewController -> UIView -> ......
3、找到响应者后,对事件进行相应的处理
响应者
1、所有继承UIResponder类的对象都是响应者
2、只有响应者才能响应和处理事件
响应链的传递,如何寻找响应者
//作用:去寻找最适合的View
//什么时候调用:当一个事件传递给当前View,就会调用.
//返回值:返回的是谁,谁就是最适合的View(就会调用最适合的View的touch方法)
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
//1.判断自己能否接收事件
if(self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.01) {
return nil;
}
//2.判断当前点在不在当前View.
if (![self pointInside:point withEvent:event]) {
return nil;
}
//3.从后往前遍历自己的子控件.让子控件重复前两步操作,(把事件传递给,让子控件调用hitTest)
int count = (int)self.subviews.count;
for (int i = count - 1; i >= 0; i--) {
//取出每一个子控件
UIView *chileV = self.subviews[i];
//把当前的点转换成子控件坐标系上的点.
CGPoint childP = [self convertPoint:point toView:chileV];
UIView *fitView = [chileV hitTest:childP withEvent:event];
//判断有没有找到最适合的View
if(fitView){
return fitView;
}
}
//4.没有找到比它自己更适合的View.那么它自己就是最适合的View
return self;
}
//作用:判断当前点在不在它调用View,(谁调用pointInside,这个View就是谁)
//什么时候调用:它是在hitTest方法当中调用的.
//注意:point点必须得要跟它方法调用者在同一个坐标系里面
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
NSLog(@"%s",__func__);
return YES;
}
响应者如何处理事件
UIResponder内部提供了以下方法来处理事件触摸事件
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
加速计事件
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event;
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event;
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event;
远程控制事件
- (void)remoteControlReceivedWithEvent:(UIEvent *)event;
应用
由于以上找寻响应者和响应者处理事件的方法都可以重写,那么,我们是不是可以改变和控制事件的响应机制呢?当然是是了
- 在实现新功能引导图层的时候,让透明图层下的按钮响应真实的点击事件
//图层就不能响应点击
override func point(inside point: CGPoint, with event:
UIEvent?) -> Bool {
if self.responseClick{ // 按钮响应点击事件,遮罩就不能拦截点击
self.removeFromSuperview()
return false
}
return true //不响应按钮事件,拦截点击
}
- 通过重写查找事件处理者的方法来实现不规则形状点击。最常见的不规则视图就是圆形视图,在demo中我设置view的宽高为200,那么重写方法事件如下,圆以外的区域点击不会有响应
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
const CGFloat halfWidth = 100;
CGFloat xOffset = point.x - 100;
CGFloat yOffset = point.y - 100;
CGFloat radius = sqrt(xOffset * xOffset + yOffset * yOffset);
return radius <= halfWidth;
}
网友评论