iOS 13 darkmode 适配的动态颜色 cheatsheet

深色模式,作为 iOS 13 最大的新特性,从设计者角度,带来设计体系、颜色、材质、系统控件、SF Symbols 等若干方面的新的变化;对于开发者来讲,我们熟知的适配; – 屏幕尺寸 – 屏幕方向 – View 渲染阶段(指 viewDidLoad 和 viewDidAppear 两个阶段,view 的尺寸是变化的) – iOS SDK 适配 等适配维度,而后又多了一个维度, – 外观模式(dark or light) Dark mode 的适配,我们需要处理图片、背景、填充、文字和分割线的逻辑。首先是设计师对两种外观,必须设计两套不同的颜色方案。当两套方案送到开发者手上的时候,我们也需要根据不同外观应用到不同的颜色。但幸好,开发者可以做一次封装把这层逻辑封装起来,给其他开发者使用时,屏蔽内部逻辑。为了这个目的,iOS 提供了被动式适配——动态颜色; let backgroundColor = UIColor { (trainCollection) -> UIColor in if trainCollection.userInterfaceStyle == .dark { […]

Read more

SwiftUI: 苹果的一次天才尝试

时间回到一个月前的 WWDC 19 现场,当苹果宣布推出 SwiftUI 时,所有观众为其优雅的语法、 强大的实时预览 preview特性而欢呼雀跃,在发布之后几天,各路人马推入巨大的热情,研究 SwiftUI DSL 语言设计、Swift5.1 的新特性、 Combine 库的使用方法,产出了很多的文章。熟悉 Swift 语言的会从 Swift 演进的角度对新特性的来由、场景用法等深度解析;熟稔动画的作者,则用 SwiftUI 用极简的代码玩出酷炫的效果;以前玩 reactive-cocoa 类型开发模式的大佬,则对 Combine 库做了深入的探讨。 作者对 Swift 语言是新手、水平有限,这篇文章不会深入的讨论 Swift 语法特性和 Combine 的使用及实现原理。而是分享在这几星期期间,一边学习其他人的文章,一遍使用 SwiftUI 构建网易严选的 iPad 版本 —— YanxuanHD(源码见参考链接)过程中思考和感悟。从最初的惊喜到迷茫、再到困惑直到若有所得,拙作在这里抛砖引玉。 对于分享的方法,我有个小小的执念,我在学习新语言的时候,会觉得国外的一些人写的文章和书籍,很简单易懂、看完也容易记住;而我们国人写书文章很少有这种感觉。我总结了下原因; 那些的外国人设计实现的程序语言和框架,他们对程序语言和框架的了解,更丰富和立体。 我们接触的这些语言框架时候已经是个完整体,面对 1K+ 的 API,十几个模块,我们读文档的时候,他们就像是已经组装好的钟表,了解它就像是在拆钟表,直到你拆解完毕,并尝试多次组装他们,你才有知道如何分而治之,先做小模块、后组装成整体,以及各个模块的组装顺序如何协调才是最优的;但是如果是个钟表设计者,他不仅仅知道如何正确组织组装,而且知道为什么要这样做,这样做有什么好处,那样做有什么坏处,如果你知道这些 API 文档和代码里没有的额外信息,你自然会对 […]

Read more

WKWebview 加载过程中的性能指标图解

背景 讨论 WKWebview 在加载 h5 页面时,Objective-C里的 WKNavigationDelegate、window.performance.timing、WKUserScriptInjectionTimeAtDocumentStart、WKUserScriptInjectionTimeAtDocumentEnd,以及和前端最常用的document.readystate\domContentLoaded\document.onload 事件等时间维度的关系,为native和前端在相互调用时,能够明确沟通的时机。 图解 普通的200请求,注意先看图例 本次数据采集的页面是 https://mp.weixin.qq.com/s/X_WDv1-vqdXYcg0eLpMAhA, ​ ​ 带有302跳转的页面 ​ ​ 本次数据采集的页面是 https://lq.163.com/platform/wap/entry?merchantCode=M32412338855&before_login=1 请求出错时的序列 本次数据采集的页面是 https://hite.me,出错原因是因为证书不正确。 ​ ​ 对比,结论 1. 首先注意几个等价事件。 didStartProvisionalNavigation = navigationStart didCommitNavigation = domLoading  =  WKUserScriptInjectionTimeAtDocumentStart,此时刚刚开始创建 DOM WKUserScriptInjectionTimeAtDocumentEnd = domContentLoade = document.readystate = interactive,此时 CSSOM 和 DOM 都已经构建完毕,等待图片资源等下载 didFinishNavigation = domComplete = […]

Read more

探索 messageHandler 的传输性能极限

本次测试的目标是 iOS 8+ 之后提供的 WKWebview 提供的 JS 和 Native 通讯机制之 messageHandler,比较浅显的探索下它各方面的极限。 测试 Demo ##主要的测试场景包括 1. messageHandler 可传输的数据类型有哪些? 2. 以字符串为例,messageHandler 最多可传输多少字节? 3. 承接 2,在不同量级下的传输效果(是否丢失、速度等)如何? 4. 如果是 native 向 WKWebview 传输数据,是否有类似的表现? 5. 探索使用 messageHandler 的最佳方法。 ##测试方法 1. 测试设备,iPhone XR 模拟器,Xcode 10.2 2. 硬件,MacBook Pro (13-inch, 2016),Mem 16 […]

Read more

objc 中最好的多行字符串声明方式

1. 问题 在 AppHost.framework【注1】(以下简称 AppHost) 的编码中,需要处理很多预先导入到 webview 里的 js 文件,有一些不关键功能是用 .js 的文件读到内存的,还有一些比较短小的 js 源码,如; (function(e){ e.setAttribute(‘src’,’%@’); document.getElementsByTagName(‘body’)[0].appendChild(e); })(document.createElement(‘script’)); 要写到代码里和 objc 代码一起。还有,在 AppHost 里,有个 ah_doc 模块,在编写注释时,需要输出完整的 js 代码,如 window.appHost.invoke(‘startNewPage’, { ‘url’: ‘http://you.163.com/’,’title’: ‘title’, ‘type’: “push”, ‘backPageParameter’: { ‘url’: ‘http://qian.163.com’, ‘title’: ‘title’, ‘type’: ‘push’ } }) 这个字符串里包含了大量的单引号、双引号,而且为了保持可读性、维护性,需要多行输出。 […]

Read more

记一次独自带小宝宝

今天是妈妈的生日,她和其他的兄弟 3 个人去看《风中有朵雨做的云》电影,晚上 9 点到 11 点就是我和宝宝两个人了,丈母娘他们在楼下,也有自己的事情,想想自己配宝宝逗他玩,应该不是问题,所以给他们买好票,到 8 点半了,还送他们上车。 在临走之前,我还告诉老婆,让宝宝自己先吃好奶,这样就不用怕她一会需要吃奶,然后吃不到,哇哇哇的哭。 没想到我还是想的太简单了。 刚刚开始的时候我陪她在床上玩她的玩具,她对当当当响的东西,其实不是很喜欢,我自己扮成小狗,假装去咬东西,她就咯咯笑。或者冲过来,爬到我的肚子上,要去拿我在床边的电脑。玩一会,腻味了,我就抱着她玩 Animoji。 她现在已经学习到模仿和反馈了,对着小熊吐舌头。吐舌头是我自己玩 Animoji 时候她观察到的,来看看视频,差点笑死我了。 宝宝的 Animoji 然后接着和她玩耍,挤挤乐,她会拿着和床头板敲敲压压。她一会就不希望玩了,这时候,我又拿着饼干和水喂她。 其实这些我的哄娃 3 板斧就已经弄完了,这时候她好像有点困了,好好的坐着,突然自己就到后面去了,头一下子就碰到背靠上,喯的一声,也许自己困了,也顾不上哭了。 我抱着她,她头靠在我的肩膀,眼睛是闭上了,但是嘴里,嗷嗷嗷的,是不是发出哭死。因为平时都是困了,吃妈妈的奶睡过去,这时候,吃不到奶。我抱着她在屋子里绕圈,也没有用,去屋子外面走一的时候,外面有点冷,她没睡意了,是不哭了。 我试图把屋子里的灯都关了,让她慢慢睡着,还没等我把她放到床上,她自己感觉到自己要被放到床上了,两只手使劲的抓着我的衣服,一点也不放手。只好自己再抱起来。一看时间,电影才过了半小时~ 把灯打开,我和她一起吃华夫饼,她并不想吃饼干,看着我吃,自己手里拿着塑料壳子,也不捏,也不想吃,就呆呆哒,还好不哭。 我看她又开始揉眼睛了,睡意更弄了,我再次尝试斜着抱她看她会不会像去外面逛街那样睡着。结果还是没有失败了。 想想平时她和妈妈一起,虽然妈妈喂她奶的时候,还在看手机,但是她会很快就睡着,哄宝宝睡着,对妈妈来说其实是个很简单的时候。相同的工作,对于一个爸爸却并不简单。 还是抱着还是嗷嗷的哭,底下丈母娘在睡觉的,估计都被吵醒了。我手累了,把宝宝放在床上,她这是有点安静,我正要给她盖被子,我发现有个大苍蝇,在床头灯那里绕啊绕,我本能的去打苍蝇,发现宝宝在那嘎嘎嘎的笑,我正好故意做造型,故意去打苍蝇,她突然给我吸引住了,不哭了。 等我实在有点手酸了,去趴过去和她说话,没想到哇哇的哭起来了,再次抱起来,还是哭,不管是开灯关灯,就是哭,眼睛大部分时间是闭着的,就是想睡差了点喝奶,始终无法入睡。 底下老妈给老婆打了电话,狠狠的批评了她,让她回家,她说还要半小时。老妈上楼,自己尝试抱起来,哄睡,用她很久之前的方式,其实已经完全没有效果了,宝宝的身体弓成一个 反 C,还是哭成泪人,无奈我告诉她,她看我打苍蝇不哭。 所以到后面变成两个人,在玄关那里对着彩灯,挥着苍蝇拍,老妈是远视眼,看不清懂着的苍蝇,我自己一手抱娃一手拿苍蝇拍,乱打,这时候她才咯咯咯的笑起来了。 老妈拿着苍蝇拍也开始了她的表演,这时候宝宝也安静下来了。 我拿出来 iPad,她最喜欢按 home 键,她坐在我的腿上,我就问 Siri,天气怎么样啊? 我漂不漂亮啊? 明天我需要打伞吗? 。。。 这类的问题,反复问,问着问着宝宝安静了,不久宝宝睡着了, 一看时间10.55 也是妈妈们他们看完电影的时候。 […]

Read more

关于TapGesture、UIResponder 链和 target-action 事件的相互影响的机理和应用

https://github.com/hite/IOSEventTest 这是一个供探索、验证、对比测试而精心设计的demo。 用来研究 UIControl,普通的 View 在 使用 target-action, addTapGestureRecognizer 方式时,不同情况下如何相互作用。 试图解答以下问题; 1. 第一响应者如何确认?(包括 alpha,hidden,clipToBound 属性的影响,都不是本次试验的重点) 2. target-action 和 tapGesture 混用时,如何表现,加入变量 cancelsTouchesInView 时,是否有不同? 3. target-action 或者 tapGesture 是否各自都有多个? 1. 包括相同类型 event state 和 gesture Type 是否有多个? 2. 包括不同类型 event state 和 gesture Type 是否有多个? 4. 相同和不同类型 […]

Read more

WKWebview 加载过程中的性能指标图解

背景 讨论 WKWebview 在加载 h5 页面时,Objective-C里的 WKNavigationDelegate、window.performance.timing、WKUserScriptInjectionTimeAtDocumentStart、WKUserScriptInjectionTimeAtDocumentEnd,以及和前端最常用的document.readystate\domContentLoaded\document.onload 事件等时间维度的关系,为native和前端在相互调用时,能够明确沟通的时机。 图解 普通的200请求,注意先看图例 本次数据采集的页面是 https://mp.weixin.qq.com/s/X_WDv1-vqdXYcg0eLpMAhA, ​ ​ 带有302跳转的页面 ​ ​ 本次数据采集的页面是 https://lq.163.com/platform/wap/entry?merchantCode=M32412338855&before_login=1 请求出错时的序列 本次数据采集的页面是 https://hite.me,出错原因是因为证书不正确。 ​ ​ 对比,结论 1. 首先注意几个等价事件。 didStartProvisionalNavigation = navigationStart didCommitNavigation = domLoading  =  WKUserScriptInjectionTimeAtDocumentStart,此时刚刚开始创建 DOM WKUserScriptInjectionTimeAtDocumentEnd = domContentLoade = document.readystate = interactive,此时 CSSOM 和 DOM 都已经构建完毕,等待图片资源等下载 didFinishNavigation = domComplete = […]

Read more