快来体验你的暗黑模式骨架屏

3,240 阅读3分钟

前言

暗黑模式(Dark Mode)是iOS13推出的新功能,将传统的UIColor升级成dynamicColor。

TABAimated在v2.2.3实现了自动转换暗黑系列骨架屏。
本文讲解在v2.3.0版本的暗黑模式实现。

TABAnimated的骨架层是用CALayer实现的,但是CGColorRef并不能成为动态颜色,所以本文也将说明TABAnimated是如何实现动态的CGColorRef。

先睹为快

包括四种动画在内,多种应用场景,均以完美适配暗黑模式。

工具箱切换.gif

setting设置切换.gif

新增Api

属性 全局类 局部类 含义
darkAnimatedColor TABAnimated TABViewAnimated 暗黑模式骨架屏内容颜色
darkAnimatedBackgroundColor TABAnimated TABViewAnimated 暗黑模式骨架屏背景颜色

开发者需要做什么?

原则上什么都不需要,但是背景颜色、内容颜色和各自产品有关,所以开放了对应属性。

通过gif,你发现了什么?

如下图,在已经切换暗黑模式后,进程卡片列表页面没有刷新,如果是UIColor系统会自动刷新,CGColorRef暂时没有找到办法处理。

卡片列表.png

结构图

image.png

暗黑模式实时性原理

我们知道只有UIView、UIViewController、UIPresentationController才能监听模式切换事件。

通过给予控制视图添加一个透明、size为(.1, .1)的哨兵视图,监听哨兵视图的traitCollection的变化, 再将该消息传递给暗黑模式管理者协议

哨兵视图的管理者自然也是暗黑模式管理者。

暗黑模式管理者协议

为了进一步与生产层解耦,引入了TABAnimatedDarkModeManagerInterface协议

// 绑定controlView
- (void)setControlView:(UIView *)controlView;

// 添加哨兵视图
- (void)addDarkModelSentryView;

/// 添加需要实时改变的view
- (void)addNeedChangeView:(UIView *)view;

// 释放
- (void)destroy;

1. setControlView

生产层在绑定controlView视图时,同时给予暗黑模式管理者绑定该controlView。

暗黑模式管理者需要controlView的原因:
获取controlView的traitCollection、tabAnimated,以提供给暗黑模式主体

2. addDarkModelSentryView

生产层绑定controlView后,给予controlView添加一个哨兵视图。 该哨兵视图用于监听traitCollection的变化

3. addNeedChangeView:

controlView视图的骨架屏主体不一定是其本身,比如UITableView是其上的cell。 该接口会将新生成的view加入到管理列表中

4. destroy

生命周期结束后,销毁不需要的对象

如何自定制骨架屏暗黑模式转换?

需要新建类,遵循自TABAnimatedDarkModeInterface

/// 暗黑模式转化协议主体,开发者可重写
/// TABAnimatedDarkModeImpl是该协议默认的实现,根据traitCollection、tabAnimated自动转化backgroundLayer、layers的属性
/// @param traitCollection 当前的traitCollection
/// @param tabAnimated 目标tabAnimated
/// @param backgroundLayer 目标背景layer
/// @param layers 目标layers
- (void)traitCollectionDidChange:(UITraitCollection *)traitCollection
                     tabAnimated:(TABViewAnimated *)tabAnimated
                 backgroundLayer:(TABComponentLayer *)backgroundLayer
                          layers:(NSArray <TABComponentLayer *> *)layers;

开发者根据入参所提供的traitCollection来判断当前模式, 根据tabAnimated获取控制视图的参数,最后根据自己的骨架、动画需求,自行调整暗黑风格。

模式禁用

apple本身是支持局部、全局禁用暗黑模式的,骨架屏同样会跟随你的禁用而禁用暗黑系骨架屏。所以对于骨架屏而言,除了配置颜色外,你不需要做任何其他多余的事情。

不能兼容的情况

后台卡片列表显示页面不能实时刷新。 解决方案:骨架层由CALayer换成UIView(这种方案不予采用)