看到任务栏里静静躺着的 Xcode,突然想起当时考虑买 MacBook 其中一个诱因就是也可以进行一些 iOS 开发了。闲的时候去试了试 Swift UI,跟着 Apple 官网的 Swift UI 教程写了一个小 Landmark App,这个过程体验实在是很惊艳...

首先,在 Code Editor 区域所有改动,全部在右边都有实时渲染当前界面。点击右边 Preview 的对应 Element,还可以进行几乎所有 attribute 的修改和调整,并且所有修改和调整都会同时再同步回 Code Editor。这个体验是我身为一个前端开发者都感到惊艳的。要知道,网页端的 prototype 算是相对非常容易的了:写几个简单的 CSS,加几张图可能一个设计图界面就差不多了,之后浏览器打开 Inspector,微调一些 CSS,就完工了。但浏览器里的 CSS,一来若想重新 apply 回自己的 code,要不然手动复制粘贴,多的话就只能创 inspector-stylesheet,甚至还要自己手动 merge 进之前的 style。在 Xcode 中,这一切都是自动实现与同步的,整个编辑界面不再是分隔开的两个元素:Code Editor & Preview,他们现在已经融为一体,互为弥补,成为真正的 WYSIWYG Editor - Swift UI Edition xD

然后说说模拟器:我使用的是 Xcode 13,支持新出的 iPad Pro(“全面屏”版本),可以直接运行模拟器。在打开模拟器后,惊艳地发现,iPad Pro 的光标竟然可以直接与 MacBook 的 Trackpad 映射,甚至在支持 3D Touch 的机型(iPhone XS, iPhone XS Max 等)上,是可以直接将 Trackpad 上的 Force Touch 压感直接映射至模拟器内的,我当时惊讶地合不拢嘴... 渲染效率也是一流,在我的 MacBook Pro 2019 上,创一个虚拟 4K 显示屏并分屏播放 4K 视频,竟然几乎不卡... CPU 占用也大致在 40% - 50% 上下。要知道这是模拟器,这样的转译效率已经很高了。(后期去查了查,iOS 在 Mac 上的模拟器是直接跑的 x86 而不是 arm... 竟然有这样的操作...)

接着就是 Swift UI 的体验上了。Swift UI 的字体全部都有预设变量,标题、副标题等的文字大小与样式,都是预设的,这样开发者们在写 UI 的时候就完全不用自己去一个个调。并且这带来了非常巨大的 Accessibility 适配灵活度:在调整系统显示字体大小时,iOS 会自动根据 UI 内的 “标题” “副标题” 等语义化定义,自动调整至对应合适大小。同样的,使用 Swift UI 进行语义化设计,也可以让 App 自动适配 Dark Mode,在全部使用系统 UI 进行绘制的情况下,毋需再做任何处理。

综上所述,我觉得 App Store 上的 App 设计都相对统一以及符合开发规范就是这个原因。当然这里面不排除 Apple 在审核 App 时定下的一大堆霸王条款和相对激进的审核方式的因素,但是我个人觉得,在提供了这么好的一套开发流程后,进行相对应的质量控制也不无道理。使用原生 UI 绘制还有很多好处,比如未来的 iOS 更新适配也会相对简单,因为系统会帮我做一大部分;比如增加对 iPad 甚至 Apple Watch 等其他设备的支持也十分容易;还比如增加对视障人群的支持。

这就有了一个巨大的好处:开发者会源源不断地往这个生态输送高质量、并且是用 Apple 自己语言写出来的语义化的 App,自然整个系统的排版设计乃至交互优化,就都掌握在了 Apple 手里了,他们优化也可以游刃有余。作为对比,Android 一个较大问题就是,需要做一些向下兼容的工作、以及原生框架很难写;这就导致大家分分开始用第三方框架,自然设计不统一;并且由于第三方框架的原因,这些开发者都在“重复干一件别人已经干过的事情”,开发效率就会低:他们需要各种适配,需要和不同的定制 ROM 对线,需要针对各式异形屏(Android 10 标准中就已经内置了 6 种不同标准:无、居中窄刘海、居中宽刘海、左/右圆形挖孔、左/右圆角矩形挖孔、水滴)做特殊优化。如果想做到最基础的适配所有潜在用户群,那么这所有的屏幕类型 Android 开发者都要一对一针对性地进行优化,工作量直接暴增,还都是吃力不讨好的事情:不同屏幕使用体验有时也会产生不同,比如挖孔屏用户在使用视频播放软件的时候,有的希望画面尽可能宽但是可能会因为挖孔缺掉一部分,有的希望画面显示完整但是可能会小一大圈,这些都是很难解决的问题。

前几天写网页做 iOS PWA 优化(这一点 Apple 做的就挺差的了... PWA 体验至今还是非常差)Apple 在网页这边就留了四个参数:上下左右的“绘制安全区域” safe-area-inset-{left,top,right,bottom},只要在这些安全区域外绘制 UI,就绝对没问题,并且也是动态的(Safari 在开始浏览网页后,向下滑动浏览更多内容时,底栏会隐藏、顶栏会缩小,这个过程是 “滑多少就有多大的 Safe Area”,这样我就可以通过使用 CSS transition 属性非常方便地增加底部浮动的 Element 在用户隐藏底栏后的动效。但是另一边,我没法适配 Android 的异形屏:因为现在还没给Standard 如何进行适配。iOS 还会提供当前系统的 Dark/Light Mode 的 env() 数据。

有的时候实在是不得不佩服。虽然我真的想用 Android:iOS 这边太多东西配置不了,用起来有时候真的不顺手,重复性操作太多。但,很多原因,我暂时还是没换 Android。手边的 OnePlus 7 Pro,平常也只是做网页适配、刷方舟了。