写点什么

优酷暗黑模式(十):消费场景落地(iOS)

  • 2020-02-28
  • 本文字数:3836 字

    阅读完需:约 13 分钟

优酷暗黑模式(十):消费场景落地(iOS)

一、概述

iOS 13 中苹果引入了暗黑模式,提供了全新的配色方案,非常适合暗光环境下使用,对眼睛的伤害更小。为了配合优酷 App 全站暗黑模式的适配,我们需要在优酷主客消费场景将暗黑模式全面落地。


值得庆幸的是,在这之前优酷主客消费场景已经完成了统一架构迁移和性能优化,并在这个过程中完成了大部分插件的治理,遵循统一架构、组件标准化、DesignToken 设计,使得消费场景可以快速高效地支持暗黑模式。

二、业务介绍

优酷主客消费场景即优酷 App 的播放页。播放页作为视频内容消费的落地页,主要提供视频播放、视频内容介绍、互动、视频推荐、视频花絮、视频周边等内容推荐,业务场景及页面内容都比较复杂。根据场景分为:剧集、电影、综艺、少儿、体育、新知等;其内容有:组件、半屏、Tab 等。


组件:即视频相关内容承载控件,包括简介,选集,周边视频,花絮视频,推荐视频等,通过这些内容,让用户了解更多的视频相关的信息。


半屏:包括 Native、Weex、H5 的半屏,通过半屏用户可以看到更多的视频相关内容,也可以承载视频互动。因为组件展示的内容还是有限,通过半屏可以更好更全地展示。


Tab:通过 Tab 让用户在不同的内容之间切换。


播放页架构图:


1)页面、组件、坑位结构图:



2)业务效果图:


三、适配策略

1、页面适配

页面展现主要分为几种状态:加载态(Loading),展现态,异常态。主要工作可以分为加载态 LoadingView 适配,展现态背景色适配,异常态 ErrorView 适配。


按道理来说,背景色适配工作量会非常大,因为需要一层一层地去设置子 View 的背景色。但是由于优酷的视图中,大部分背景色是透明的,使得在进行暗黑模式适配的过程中非常便利,不用去一层一层的设置背景色,只需要适配容器 View 就可以。


[self.containerView setBackgroundColor:UIColor.ykn_primaryBackground]; //设置背景色,ykn_primaryBackground 为我们暗黑模式框架对外暴露的属性通过它可以取到对应的颜色[self.view setBackgroundColor:UIColor.ykn_primaryBackground]; //设置背景色
复制代码

2、组件适配、坑位适配

因为播放页都已经拆分为组件和坑位,所以完成页面部分的适配之后,主要就是对组件和坑位的适配。由于播放页组件完成度很高,所以在进行组件适配的时候也是比较顺利的。举个例子,播放页很多的组件都有 Header View,即左面会有文字,右面有一个箭头的 image。



当替换完 Header View 组件的图片,并进行完文字的暗黑模式适配后,所有这些 UI 布局全部完成了适配工作,从这里可以看出组件标准化的完成程度对后期业务的维护有着深远的影响。


_titleLabel.textColor = UIColor.ykn_primaryInfo;   //设置组件头部标题颜色_subtitleLabel.textColor = UIColor.ykn_secondaryInfo;  //设置组件头部副标题颜色_arrowImageView.image = UIImage.ykn_detail_comp_header_more;   //设置组件头部箭头图片
复制代码

3、半屏适配

半屏页面主要是分为 Native 半屏页面、H5 半屏页面、Weex 半屏页面。


由于所有的半屏页面都是由播放页半屏容器管理器来管理,所以只需要在里面统一适配即可;需要注意的是我们适配的只是 H5、Weex 的容器,容器里面的具体页面的适配详见: 暗黑模式的技术支撑(Weex&H5)。


举例来说,H5 半屏容器页面适配:


webViewController.view.backgroundColor = UIColor.ykn_primaryBackground;  //设置容器背景色webViewController.topBar.backgroundColor = UIColor.ykn_primaryBackground; //设置顶部导航背景色webViewController.titleLabel.textColor = UIColor.ykn_primaryInfo;  //设置顶部导航字体颜色[webViewController.closeBtn setImage:UIImage.ykn_detail_box_close forState:UIControlStateNormal];//设置顶部导航关闭按钮图片
复制代码

4、中间件处理,与沉浸式隔离

在适配暗黑模式之前,优酷播放页已经完成了沉浸式模式的开发。沉浸式使得用户可以快速地融入到内容本身中去,减少不必要的信息造成的视觉干扰,使用更有层次感的内容来引导用户聚焦,自然地实现播放器视觉 C 位呈现,其呈现效果与暗黑模式也有较大不同。


所以,在适配的过程中需要做一层颜色及资源管理层(架构图中的颜色资源管理层),来区分沉浸式氛围及暗黑模式。通过不同的开关控制背景处理及加载不同的资源、颜色。后期沉浸式模式将会接入优酷 App 的全局统一氛围配置,做到自动下发氛围相关样式,减少适配工作。



在进行与沉浸式隔离开发的时候我们遇到一个难点,在没有进行暗黑模式适配时候,沉浸式是通过函数


-(NSString *)immersionImageName:(NSString *)imgName


进行适配,该函数实现逻辑如下:


-(NSString *)immersionImageName:(NSString *)imgName{   if (self.isImmersionMode) {       NSString *name = [self.imgNameDic valueForKey:imgName] ? : imgName;       return name;   } else {       return imgName;   }}
复制代码


该函数首先会先判断是否为沉浸式模式,如果为沉浸式返回对应沉浸式的图片名称; 当找不到对应图片时,使用一个兜底图片。如果沉浸式没有生效则直接返回正常图片名称。


当适配暗黑模式时候遇到了难点,优酷设计标准化 SDK 是通过属性调用返回 UIImage 对象,所以需要改造该函数。


先贴上改造后结果:


-(UIImage *)immersionImage:(NSString *)imgName{   if (self.isImmersionMode) {       if ([self.imgNameDic stringForKey:imgName]) {           return [UIImage imageNamed:[self.imgNameDic stringForKey:imgName]];       }   }   SEL sel = NSSelectorFromString(imgName);   if ([UIImage respondsToSelector:sel]) {       return [UIImage performSelector:sel];   } else {       return nil;   }}
复制代码


首先将函数返回结果改为 UIImage 对象。这么改造有两点好处:


第一: 在业务方调用时,可以直接使用该函数返回的结果,不需要再调用函数


(nullable UIImage *)imageNamed:(NSString *)name


便于业务方使用。


第二: 如果当前为暗黑模式,可以直接返回该属性值,不需要进行转换等操作,提高运行效率、降低出错概率。


最后: 因为传进来的是图片名称,并且属性名称是与图片名称一致的,所以可以通过其属性 get 方法拿到对应图片。


总结一下该函数的逻辑:如果为沉浸式模式,返回对应的沉浸式 UIImage 对象 ,因为沉浸式业务优先级大于暗黑模式。如果不是沉浸式,通过 NSSelectorFromString 生成该属性 get 方法对应的 selector,判断是否存在该方法。如果存在该方法说明存在对应图片,调用该属性 get 方法并返回对应 UIImage 对象。

5、网络图片的适配

暗黑 SDK 是直接支持本地图片适配的,但是网络图片适配需要业务方来做。在播放页,有些图片是支持后台配置的。即当后台配置了图片下发,优先展示后台配置的图片,如果后台没有配置图片则展示本地图片。


例如下图中的热评、收藏、缓存、分享对应图片都是支持后台配置的。



那么问题来了,这种情况下如何进行暗黑模式的适配?


解决方案为提前准备好从网络下载的图片,对应的图片有两套即正常模式和暗黑模式。使用时候判断对应模式来使用对应图片。


示例代码如下:


UIImage *imageFromWeb1 ;//从网络下载成功的UIImageUIImage *imageFromWeb2 ;//从网络下载成功的UIImageUIImage *image = [UIImage ykn_imageWithThemeProvider:^UIImage * _Nonnull(__kindof YKNThemeManager * _Nonnull manager, NSString * _Nullable identifier, NSObject<YKNThemeProtocol> * _Nullable theme) {             //回调中不要做耗时操作,如是网络图,提前准备好图片             if ([identifier isEqualToString:YKNThemeIdentifierDark]) {                 return imageFromWeb1 ;  //dark模式下的图             }             return imageFromWeb2; //light模式下的图         }];
复制代码

四、适配效果


五、调试小技巧

在进行暗黑模式适配时候遇到这样一个问题,即每次改过 UI 我们都需要重新运行整个 App 才会生效。毫无疑问,这是十分浪费时间的,有没有什么方案可以做到不重新运行 App 即可生效的呢?答案是有的。


在模拟器上我们可以通过 InjectionIII 来进行热更新,具体方案不再赘述,网络上有很多介绍文档。这里只介绍真机实现方案。


实现方案:首先添加一个断点,接下来编辑断点并添加一个 Debugger Command 并输入表达式,最后选择 Automatically continue after evaluating actions。为什么要勾选这个呢?如果勾选上运行到该断点的时候不会停住,会自动执行表达式,并自动执行下一行代码。


六、项目总结

业务架构层面核心功能组件化的好处是巨大的,这使得代码按照功能模块高度聚合,只需要针对当前功能组件进行修改即可全局生效;UI 层级的扁平化及层级管理也是十分重要的。


通过暗黑模式的适配,大大的提升了优酷播放页的使用体验。这也是我们对 iOS 13 新特性的一个探索,并且在较短时间内拿出来一个成熟的暗黑模式适配方案,在优酷 iOS 端进行了尝试和使用,最终呈现的效果也是非常好的,通过这次的改造和实践也为我们以后对其它新技术的探索打了坚实的基础。


作者简介


子荀、金籽,阿里文娱无线高级开发工程师。


相关阅读


优酷暗黑模式(一):是什么、为什么、如何落地?


优酷暗黑模式(二):如何建立设计语言标准化管理体系


优酷暗黑模式(三):暗黑模式设计指南


优酷暗黑模式(四):设计标准化的技术实现


优酷暗黑模式(五):暗黑模式的技术实现策略


优酷暗黑模式(六):暗黑模式的技术支撑 iOS


优酷暗黑模式(七):暗黑模式的技术支撑 Weex & H5


优酷暗黑模式(八):分发场景落地(Android & iOS)


优酷暗黑模式(九):消费场景落地(Android)


2020-02-28 15:001719

评论

发布
暂无评论
发现更多内容

如何使用Redis实现分布式锁?

王磊

Java Java面试题

2023 ARTS 打卡第一周

Z.

ARTS 打卡计划

开源Java诊断工具Arthas:开篇之watch实战

javalover123

Java 开源 Arthas watch 诊断

ARTS 打卡第 12 天

自由

ARTS 打卡计划

2023 ARTS打卡第一周

犇犇

ARTS 打卡计划

文心一言 VS 讯飞星火 VS chatgpt (79)-- 算法导论7.4 4题

福大大架构师每日一题

福大大架构师每日一题

GPT大语言模型引爆强化学习与语言生成模型的热潮、带你了解RLHF。

汀丶人工智能

强化学习 ChatGPT AI大语言模型

华为云开发工具CodeArts IDE for C/C++ 开发使用指南

华为云PaaS服务小智

ide 开发工具 华为云 开发环境

企业级私有化部署即时通讯,完美替代SaaS平台

WorkPlus

企业级即时通讯协作和移动应用管理平台哪个品牌好?

WorkPlus

一云多芯能力再获认可!天翼云助推政企上云行稳致远!

天翼云开发者社区

云计算

C++的对象与类的含义

梦笔生花

使用 Terraform 与事件驱动的 Amazon CodeBuild 提升云上数据应用运维效率

亚马逊云科技 (Amazon Web Services)

云原生

【ARTS】Week 1

小小

ARTS 打卡计划

助力人工智能教育普及 宾果智能机器人走进全国千所小学

硬科技星球

Prompt-“设计提示模板:用更少数据实现预训练模型的卓越表现,助力Few-Shot和Zero-Shot任务”

汀丶人工智能

人工智能 Prompt prompt 工程

ARTS 打卡第 1 周

orient

ARTS 打卡计划

Programming abstractions in C阅读笔记:p123-p126

codists

近期大型攻防演练观感及未来攻防趋势判断

墨菲安全

安全 软件供应链

从来不懂K8s的人在10分钟内将应用跑在了K8s中

北京好雨科技有限公司

Kubernetes 开发者 云原生 应用部署

为什么Nop平台坚持使用XML而不是JSON或者YAML

canonical

json xml 低代码 Nop平台

ARTS打卡Week1

JimDeng

ARTS 打卡计划 go modules

Presto 设计与实现(六):JMX

冰心的小屋

数据湖 JMX presto presto 设计与实现

ARTS 打卡第 1 周

AI帅辉

ARTS 打卡计划

【深度学习 | 感知器 & MLP(BP神经网络)】掌握感知的艺术: 感知器和MLP-BP如何革新神经网络 - ARTS 打卡第 二 周

计算机魔术师

人工智能

LangChain + Streamlit + Llama:将对话式AI引入本地机器

3D建模设计

人工智能 LLM

领域驱动设计(DDD):从基础代码探讨高内聚低耦合的演进

付威

架构 领域驱动设计 DDD

ARTS打卡第一周

苏籍

技术 ARTS 打卡计划 #成长经验

如何使用LLM实现文本自动生成视频

3D建模设计

Python 人工智能

一个炫酷的头像悬停效果 2

南城FE

CSS 前端 动画 SASS 交互

媲美ps的图像编辑推荐 Pixelmator Pro 直装激活中文版

胖墩儿不胖y

图像编辑 编辑图像 图像处理工具

优酷暗黑模式(十):消费场景落地(iOS)_移动_阿里巴巴文娱技术_InfoQ精选文章