iOS面试题(三) UI视图- UI事件传递&响应

UI视图

  • UITableView相关(重用机制的理解和运用方面,包括我们在UITableView的使用过程中,会涉及到对数据源的一个多线程的操作,这里面就涉及到了一个数据源同步的问题)

  • 事件响应&视图响应

  • 图像显示原理(UI视图的图像显示原理是怎样的?我们创建了一个控件,最后是如何转化到屏幕上的每一个像素点的呢?)

  • UI卡顿、掉帧

  • UI绘制原理/异步绘制原理

  • 离屏渲染

  •  

UI事件传递&响应 相关面试问题


1.UIView和CALayer之间的关系和区别

  (1)关系:
                  


     ① UIView中有个属性layer(CALayer类型)和backgroundcolor。layer就指向了一个CALayer类型的变量

     ②  实际上UIView的backgroundcolor是CALayer同名属性方法的一个包装(重写CALayer的backgroundcolor)

     ③ UIView的显示部分是由CALayer的显示的内容contents来决定的。
     ④ contents对应的backing store实际上是bitmap类型的位图,最终我们显示到屏幕上面的对应UI控件可以理解为都是位图。

(2)区别:
         ①:UIView为其提供内容,以及负责处理触摸等事件,参与响应链
         ②: CALayer负责显示内容contents
             
  (3) 为什么UIView只负责它的时间传递以及视图响应链这样的一个机制流程,而显示部分的工作都由CALayer来做呢?为什么如此设计?    
         遵循单一职责设计模式,体现了一个职责上的分工。

2.事件传递与视图响应链
                     

                                      
     点击ViewC2的的空白区域,系统是最终怎样的方式才找到了最终事件响应的视图是C2的呢?

  1. 事件传递流程


                           

(1)点击屏幕时首先将事件传递给UIApplication,UIApplication将事件传递给UIWindow

(2)UIWindow调用hitTest返回响应视图,先通过pointInside:判断是否在UIWindow范围内,如果在的话会通过倒序的方式遍历UIWIndow的子视图找出响应视图,最后添加的子视图会最先调用hitTest方法,递归调用hitTest返回找到的视图。

2.hitTest:withEvent内部实现流程图
                        

 

 // 返回最终响应事件的视图view
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    if (!self.userInteractionEnabled ||
        [self isHidden] ||
        self.alpha <= 0.01) {
        return nil;
    }
    //pointInside:withEvent方法里面自定义点击条件
    if ([self pointInside:point withEvent:event]) {
        //遍历当前对象的子视图
        __block UIView *hit = nil;
        //NSEnumerationReverse 倒叙遍历
        [self.subviews enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            // 坐标转换
            CGPoint vonvertPoint = [self convertPoint:point toView:obj];
            //调用子视图的hittest方法
            hit = [obj hitTest:vonvertPoint withEvent:event];
            // 如果找到了接受事件的对象,则停止遍历
            if (hit) {
                *stop = YES;
            }
        }];
        
        if (hit) {
            return hit;
        }
        else{
            return self;
        }
    }
    else{
        return nil;
    }
}
 // 判断点击的位置是否在当前视图的范围内
- (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event;  

3.视图事件响应方法

- (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;
  • UIResponder的方法,UIView继承自UIResponder,响应触摸方法
  •  C2-->B2-->A-->UIView不处理触摸事件则一层层往上传递直到UIWindow(视图响应链)
  • 如果传递到UIApplicationDelegate都不处理则忽略


 

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值