1、骨架屏简介:
骨架屏 Skeleton Screen Loading 也叫加载占位图,是近年流行的加载控件,通常表现形式是在界面上待加载区域填充灰色的占位图,与线框图的效果非常相似。Skeleton Screen就是在页面数据尚未加载前先给用户展示出页面的大致结构,直到请求数据返回后再渲染页面,补充进需要显示的数据内容。相比于之前的Loading动画,骨架屏页面更容易让用户产生一种错觉,页面快加载完了。
优点:
预加载界面大致结构,提高用户体验。
缺点:
对于一些复杂的UI适配难度比较大。
库的地址:https://github.com/tigerAndBull/TABAnimated
接下来研究下这个骨架效果是如何实现的:
2、TABAnimation动画实现原理:
骨架动画的实现,主要核心包括以下几步:
- 生成骨架元素
- 加工并装饰骨架元素
- 配置骨架视图,启动动画,并绑定到原始视图
- 结束动画,移除骨架视图并显示原视图
2.1、TABAnimation库结构分层
- 控制层:由控制模型绑定参数、把握时机,向生产层输送生产任务
- 生产层:生产层拿到生产任务,使用内置缓存机制、复用池、生产流水线进行生产。
- 加工层:加工层将已经生产好的产品进行加工。主要通过动画协议、暗黑模式协议、调整协议,而协议的控制权交由控制层。所以即便是加工层的任务,开发者也只需要聚焦于控制层开放的api。
2.2、TABAnimation骨架动画实现:
TABAnimation实现骨架动画,主要核心内容是围绕着一个骨架产品Production来做的,其伴随着骨架动画的的整个生命周期,从生成到骨架的结束。每一个要实现骨架屏的View都会绑定一个骨架Production,其作用就像一个数据model,开始的时候使用它来获取收集数据,后期利用它来渲染骨架动画,我把其总结如下图:
先查找有没有生成的Production,如果有,那么直接绑定到View上就OK,如果没有,那么需要创建,代码如下:
2.2.1、 Production的创建过程:
- 生成背景层Layer
- 递归遍历原视图子View,并生成对应的骨架Layer
- 链式编程,调整骨架Layer的大小
- 将生成的Layer绑定到Production
- 将生成好的Production缓存到本地
2.2.2、Layer创建过程以及关键代码:
创建的时候,分为对普通视图的创建和对表格视图的创建
1、普通视图View创建:
这里将生成过程中产生的大量对象包含在autoreleasePool块中,优化了内存空间的使用。
2、表格视图View的创建:
- 注册重用Cell
- 交换TabelView的代理和数据源
- 刷新tableView
交换的代理方法的关键代码:
调用代理方法的关键代码:
2.2.3、创建背景Layer并绑定到Production上:
生成背景层后,将其绑定到Production产品上:
1、创建子Layer数组,并绑定到Production上:
循环遍历view,根据子View生成对应的骨架Layer:
2、确定骨架Layer的Frame大小并绑定到Production:
3、将生成的Production缓存到内存以及沙盒文件中:
这里使用了递归锁来保证线程的数据同步,同时,在写入线程的时候,为了减少开销,使用了runLoop技术来保活子线程,减少创建子线程的开销。
2.2.4、装饰并且启动动画
- 确定背景Layer的Frame大小,并addSubLayer到原始View上面
- 循环遍历子Layer,并将子Layer依次addSubLayer到背景Layer上面
- 判断是否启动暗黑模式,调整骨架颜色
- 根据动画类型,为骨架增加动画
Production作为一个核心数据模块,在每一个事件处理中起到提供数据的作用。
下面是确定背景Layer以及循环addSubLayer的关键代码:
以上便是TABAnimation类库的所有核心代码,下面贴上其对应的UML类图结构: