【iOS】iOS面试知识点学习(UI相关,完结)

本文深入探讨了iOS开发中的UI组件,包括UIView与CALayer的关系,事件传递与视图响应链的工作原理,以及图像渲染、动画原理等核心概念。详细解释了hitTest:withEvent:和视图响应链流程,介绍了Core Animation流水线和渲染过程。此外,还讨论了动画的多种实现方式,如逐帧动画、关键帧动画、隐式动画及其背后的实现机制。
摘要由CSDN通过智能技术生成

前言

总的而言,就我这将近一年的工作经历来说,成长真的是远远不足。

如果突然有天公司把我辞退,想要通过社招找到一份称心的工作,以我现在的水平来说可能真的是有点痴心妄想了。

出于这种虚无的紧迫感吧,尝试学习/复习/巩固一下iOS开发的知识点,以其在未来不至于那么被动吧。


全篇图文基本自网络,属于知识总结,如有错漏欢迎指出


UIView与CALayer

(一)

UIView是iOS系统中界面元素的基础,CALayer管理UIView的绘图部分,所以UIView本身更像是一个CALayer的管理器,访问它的跟绘图和跟坐标有关的属性,例如frame,bounds等等, 实际上内部都是在访问它所包含的CALayer的相关属性

(二)

UIView为CALayer提供内容,继承自UIResponder,负责处理触摸等事件,参与响应链

CALayer负责显示内容contents

UIView 是 CALayer 的CALayerDelegate

(三)

UIView有一个layer属性,返回主CALayer实例。通过重载UIView的layerClass方法可以让UIView使用不同的CALayer

- (class) layerClass {
    return ([CAEAGLLayer class]);
}

CALayer类似UIView的subView树形结构,也可以在layer上添加subLayer完成特殊的显示

grayCover = [[CALayer alloc] init];
grayCover.backgroundColor = [[[UIColor blackColor] colorWithAlphaComponent:0.2] CGColor];
[self.layer addSubLayer: grayCover];

(四)

CALayer具有隐式动画:在修改CALayer(非根层)的属性的时候,会自动的产生一些动画,但是在修改UIView的属性的时候并不能产生动画。主要表现在:1.bounds 在修改CALayer的宽度和高度的时候,会产生动画效果;2. backgroundColor 3.position 修改这个属性,会产生平移动画。


事件传递与视图响应链

总结起来一句话:通过事件传递找到响应事件的起点,通过视图响应链找到处理事件的终点。

(一)事件传递两个核心方法

- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event;
- (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event;

第一个方法返回一个UIView,是用来寻找哪一个视图响应这个事件

第二个方法用来判断某一个点击的位置是否在视图范围内

(二)事件传递的流程

事件传递流程描述

  • 点击屏幕产生触摸事件,系统将事件加入到一个由UIApplication管理的事件队列中,UIApplication会从消息队列里取事件分发下去,首先传给UIWindow
  • UIWindow调用hitTest:withEvent:方法寻找响应的视图,其中就会用到pointInside: withEvent:去判断当前点击的point是否在UIWindow范围内,如果是,就去遍历它的子视图来查找最终响应的子视图
  • 子视图按倒序遍历,也就是说最后添加的子视图会最先遍历。在每一个视图中都回去调用它的hitTest:withEvent:方法(同样通过pointInside: withEvent:去判断当前点击的point是否在子视图范围内),可以理解为是一个递归调用
  • 最终返回一个响应视图,如果返回视图有值,那么这个视图就作为最终响应视图,结束整个事件传递;如果没有值,那么就会将UIWindow作为响应者(?)

(三)hitTest:withEvent:

hitTest:withEvent:流程描述(不重写的情况下)

  • 首先判断视图的hiden属性、是否可以交互以及透明度是否大于0.01,如果满足条件则进入下一步,否则返回nil
  • 调用pointInside: withEvent:方法来判断这个点是否在当前视图范围内,如果满足条件则进入下一步,否则返回nil
  • 然后以倒序方式遍历子视图,每个视图调用hitTest:withEvent:,如果有最终响应视图,那么就将这个视图返回给当前视图,否则当前视图作为最终响应视图返回。

注意:如果Touch位置超过了视图边界,hitTest:withEvent方法将忽略这个视图和它的所有子视图。也就是说,即使子视图超过了视图边界(视图的ciipsToBounds属性为NO)并且包含了发生的Touch也不会返回自己。

(四)重写方法

重写事件传递的hitTest:withEvent:方法可以让视图修改返回给上一级的视图对象,需要考虑是否还需要调用super方法来获得子视图的结果。比如点击一个透明的容器视图,如果点击到没有子视图的部分,可以返回nil来让上一级继续事件传递。

重写pointInside: withEvent:则可以让视图针对自己的点击事件返回自定义的值。比如在点击到按钮的透明部分时返回NO,认为没有点击到按钮。

(五)视图响应链流程

事件传递和响应过程是相反的。

如果hitTest:withEvent:找到了第一响应者initial view,但是该响应者没有处理该事件,那么事件会沿着响应者链向上传递:第一响应者 -> 父视图 -> 视图控制器,如果传递到最顶级视图还没处理事件,那么就传递给UIWindow去处理,若window对象也不处理那么就交给UIApplication处理,如果UIApplication对象还不处理,就丢弃该事件(但是并不会引起崩溃)

(六)视图响应的系统回调方法

能够响应事件的对象都是UIResponder的子类对象(之前说过UIView继承自UIResponder)

UIResponder提供了四个用户点击的回调方法,分别对应用户点击开始、移动、点击结束以及取消点击


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值