NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

优酷暗黑模式(十):消费场景落地(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:001542

评论

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

leetcode 20. Valid Parentheses 有效的括号(中等)

okokabcd

LeetCode 数据结构与算法 栈和队列

SpringMVC(二、请求和响应)

开源 springmvc 8月月更

数据建模已死,真的吗?

Kyligence

数据建模 数据模型 数据指标

【大厂面试真题解析】蔚来数字化业务后端一面(2022.8.6)

面试官问

后端 面试题 大厂面试 面经分享 蔚来

结合实际聊聊电平转换电路(常用电平转换电路总结)

矜辰所致

电路设计 8月月更 电平转换电路

Github爆火!程序员疯抢的Java面试宝典(PDF版)限时开源

Java工程师

Java 面试 大厂

太厉害了!华为大牛终于把MySQL讲的明明白白(基础+优化+架构)

冉然学Java

Java MySQL 编程 架构 微服务

Java完全自学手册,从外包到大厂,再到年薪100万技术大佬都靠它

JAVA活菩萨

Java 程序员面试 大厂技能 秋招 大厂面经

dubbo 长连接

石臻臻的杂货铺

dubbo 8月月更

.NET现代应用的产品设计 - DDD实践

MASA技术团队

.net DDD 实战 MASA Framewrok

Rust 入门指南(使用JSON)

王泰

rust

开源一夏│别逗,作为程序员你竟还没参与过开源项目?

开源 经验分享 签约计划第三季 8月月更

不得不服!真心被这份阿里大牛开源的“全彩版图解HTTP手册”折服了

JAVA活菩萨

Java 程序员面试 大厂技能 秋招 大厂面经

从TRPO到PPO(理论分析与数学证明)

行者AI

深圳堡垒机厂家有哪些?重点推荐哪家?

行云管家

网络安全 堡垒机 深圳 运维审计

关于使用WebStorm两年所总结的一些常用插件和功能

安安安

前端 webstorm

兆骑科创创新创业大赛平台,人才引进,项目路演

兆骑科创凤阁

国际计费系统基于Sharding-Proxy大数据迁移方案实践

京东科技开发者

数据库 系统 数据迁移

爆了!1213页LeetCode算法刷题神册(全彩),GitHub万星仅是开始

JAVA活菩萨

Java 程序员面试 大厂技能 秋招 大厂面经

java软件培训费用怎么算

小谷哥

在北京参加UI设计培训到底怎么样?

小谷哥

双Q合璧:RabbitMQ与RocketMQ,电子版手绘脑图+学习指南+面试等

冉然学Java

RocketMQ RabbitMQ 架构设计 笔记 java 日志

看完腾讯大佬90天整理的“Redis深度笔记”,我直接当场膜拜

Java工程师

Java redis 源码

vivo手机上的系统级消息推送平台的架构设计实践

JackJiang

网络编程 架构设计 消息推送 即时通讯 即时通讯IM

宁夏等保测评机构有哪些?如何选择?

行云管家

等保 堡垒机 等级保护 等保测评 宁夏

《数字经济全景白皮书》银行业智能营销应用专题分析 发布

易观分析

金融 银行 白皮书 智能营销

腾讯SpringBoot高阶笔记,限时开源48小时

冉然学Java

编程 springboot 笔记 java 日志 #开源

面向推荐的汽车知识图谱构建

之家技术

人工智能 机器学习 知识图谱 汽车

架构师学习心得总结

泋清

#架构实战营

兆骑科创创业大赛竞赛平台,双创服务,投融资对接

兆骑科创凤阁

R7 6800H标压处理器+RTX 3050独显 无畏Pro15锐龙版高能开卖

科技热闻

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