继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

iOS 响应链

ZKReadStone
关注TA
已关注
手记 52
粉丝 32
获赞 322

应用与用户的交互是一个应用的灵魂。

点击、摇动、滑动、旋转等会被系统封装成UIEvent,放到事件队列里等待UIApplication去取,然后寻找响应者,找到对应的方法并执行的过程就是响应。

这里寻找最佳响应者依靠两个方法:
方法一返回最佳响应者
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
方法二判断点有没有在返回的视图范围内
- -(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event

调用顺序是
调用方法一,在遍历找到一个视图就通过方法二判断是否符合条件,符合就返回该视图

-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event 
{
	 // 1.判断当前控件能否接收事件
   if (self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.01) return nil;
    // 2. 判断点在不在当前视图内
   if ([self pointInside:point withEvent:event] == NO) return nil;
     // 3.从后往前遍历自己的子视图
   NSInteger count = self.subviews.count;
   for (NSInteger i = count - 1; i >= 0; i--) {
       UIView *childView = self.subviews[I];
       // 把当前控件上的坐标系转换成子控件上的坐标系
    CGPoint childP = [self convertPoint:point toView:childView];
      UIView *fitView = [childView hitTest:childP withEvent:event];
       if (fitView) { // 寻找到最合适的view
           return fitView;
       }
   }
   // 循环结束,表示没有比自己更合适的view 就返回自身
   return self;
}

注意遍历子视图是从最后添加的子视图往下遍历

图片描述

如上图视图A和视图B
A、B都能响应事件。切在同一父视图上的前提下,点击中间的重叠区域,响应者是?
这就看是A先添加还是B先添加了,A先B后,根据响应链肯定是B响应
,反之则A响应

增加按钮响应范围的方法

分类里重写

-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
    CGRect bounds = self.bounds;
    bounds = CGRectInset(bounds, -10, -10);
    return CGRectContainsPoint(bounds, point);
}
打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP