评论

IOS 多端适配带给小程序的思考

现在在开发 IOS 应用时,默认是保证可以同时在 iphone 和 ipad 上运行的。不过,这就会面临一些多屏适配性问题。

IOS 多端适配

现在在开发 IOS 应用时,默认是保证可以同时在 iphone 和 ipad 上运行的。不过,这就会面临一些多屏适配性问题。

在 IOS 中写页面有两种方式,一种通过 code,直接在对应 viewController 中描述对应元素的特性即可(这种方式在大型项目中用的很多;另外一种是直接利用 storyboard,通过 UI 拖拽 加属性面板设置,来实现页面布局和设计。

其中在布局上比较重要的是 IOS 中的 constraint 概念,通过限制一个 view 在上下左右的位置 和 自身尺寸大小就可以实现布局定位的效果。

对比前端中 CSS 布局来说,可以算是简洁和高效了。也就是说,你不用再管啥 盒模型、浮动布局、margin 塌陷、inline-box 默认 padding 距离等奇怪的问题。

下文就主要介绍一下苹果体系下,如何做宽屏适配特性。

以前如果只是适配多个屏幕的 iphone 的话,实现很简单直接通过 SCREEN_WIDTH 全局宏直接怼。按照 iphone6 的 375px 宽度来进行尺寸适配。

self.leftCol.width = 20 * SCREEN_WIDTH

不过,苹果还提供了其他更多更丰富的适配工具:
* auto layout 多屏适配
* 类比 CSS 中 flex 布局的 StackView 适配
* 最新 iPad 上提供的 multitask(splitview) 适配

auto layout 多屏适配

Auto Layout 是 storyboard 里面的一个子属功能,用来进行多屏适配用的。它的主要功能是可以通过你设置的 constraints ,来动态设置 View 的 position 和 size ,达到动态适配的效果。

其中设置多屏的关键点,首先在于如何区分多屏。目前,IOS 提供了 trait 的环境变量,用来指明当前屏幕的横竖和比例关系。trait 是用来描述屏幕大小、横竖屏的一个概念集合。

还记得,在 Xcode 工具栏中,有一行指明了当前的机型和屏幕:

其中 C 代表 compact;R 代表 regular。这两个属性是用来描述屏幕短边和长边的特征。例如:

* wC hR : 本意是 width compact, height regular,那么对应就是 手机竖屏的模式
* wR hC: 本意是 width regular, height compact,那么对应就是 手机横屏的模式
* wR hR: 本意是 width regular, height regular,那么对应就是 iPad 模式

在实际代码中,你可以直接通过 traitCollection 去获取对应的 horizontalSizeClassverticalSizeClass 属性,然后通过对比值来进行判断。

    var isIpad: Bool {
        return horizontalSizeClass == .regular && verticalSizeClass == .regular
    }
    var isIphoneLandscape: Bool {
        return verticalSizeClass == .compact
    }
    var isIphonePortrait: Bool {
        return horizontalSizeClass == .compact && verticalSizeClass == .regular
    }
    var isIphone: Bool {
        return isIphoneLandscape || isIphonePortrait
    }

当然,更直接的是通过 UIDevice.current.model 来直接获取机型、屏幕旋转方向之类的变量。

Auto Layout 提供了一种可视化的方式,来让你直接设置 constraints。首先点击 Vary for Traits:

然后,针对当前屏幕适配添加对应 constraints。搞定之后,完成确认即可:

一般实践中,更直接的使用代码去描述:

 if (isDeviceIpad()) {
        mask.centerX = 1.0 * superview.centerX
        mask.centerY = 1.0 * superview.centerY
        mask.width = 0.5 * superview.width
        mask.height = 0.5 * superview.height
        return;
}

StackView 适配

苹果提供一个简便的自适应容器 StackView,有点类似 CSS 中的 flex 布局属性,你可以很容易构建一个水平或者垂直的流式布局。它最大的一个特点是会自动为里面的 UIView 构建布局约束。

UIStackView 拥有三个规则 分布方向、对齐规则、分布规则,优先指定 axis 属性,来定义布局轴的方向。这个属性的特点就是很适合用在 横竖屏切换上使用,按照 iphone 的 wRhC(横屏)、wChR(竖屏) 的 trait 设置不同的 constraint,可以得到响应式适配的效果:

  1. wRhC 横屏布局: UIStackView.axis = “horizontal”, Distribution = “Equal Spacing”

  1. wChR 竖屏布局:UIStackView.axis = “vertical”, Distribution = “Equal Spacing”

IOS multitask(splitview) 适配

IOS multitask 是 iPad 提供给 app 进行多窗口交互的一个特性,这个特性可以极大增加办公效率,不需要频繁切换 app 运行。当然,更多的时候,也是对宽屏下, app 运行的一个补充。

参考:如何在 IOS 使用 multitask

默认情况下,我们在 iPad 上默认打开的 app 叫做 primary app,通过 splitView 加入的,称为 secondary apps。 由于两个 app 都是全屏打开,所以,对于全屏下的某些权限来说,primary app 独有某些权限:
* 拥有状态栏的控制权
* (还有些权限不重要,就不说了

另外,splitView 主要针对的是 IOS 原生适配,如果想要嫁接到小程序或者 app 内应用去做的话,那可能就是 app 本身自己定义一套 splitView 规范。不过,ipad 的 splitView 规范还是很有参考性的。

整体分配的比例如下:

Landscape 分屏
Landscape 的分屏尺寸如下,将屏幕分成 3 份,只会存在 2:1 的比例,没有 1:1 等分尺寸。也就是说当有 A、B 两个 app 时,排布只会有:
* A = 1/3, B = 2/3
* B = 2/3, B = 1/3

而对于两个 app 默认的 trait 都是 wChR,也就是常规 iPhone 的交互比例大小。

Horizontal 分屏
当 iPad 处于横屏时,整体的宽度被拉长了,所以分屏的选择性就多了一个 等分, 1:1。现在 iPad 在横屏下的分屏就有 1:2 和 1:1 两种排列。同样,假设有两个 app, A、B,两者的排布方式就有:

  • A = 1/3, B = 2/3
  • A = 1/2, B = 1/2
  • A = 2/3, B = 1/3

在非 iPad Pro上,两个 app 屏幕 trait 的表达如下:

* A = 1/3 (wChR), B = 2/3 (wRhR)
* A = 1/2 (wChR), B = 1/2 (wChR)
* A = 2/3 (wRhR), B = 1/3 (wChR)

但是,在 iPad Pro 上,等比排布时,会有区分:

* 非 iPad Pro
	* A = 1/2 (wChR), B = 1/2 (wChR)
* iPad Pro:
	* A = 1/2 (wRhR), B = 1/2 (wRhR)

前文了解了 IOS 生态下的多端适配,它主要有两个思路:一个是提供多种自适应组件,去实现多端适配的交互;另外一种是专门针对某个硬件设备屏幕,提出突破 app 层的交互,最有特点的就是 splitView。

这也可以带给我们很多启发,在小程序中如何做到最优的体验适配,以及能否带给开发者突破 小程序 层面的交互体验,这也是另外一个主要突破方向。

参考文献:

点赞 3
收藏
评论
登录 后发表内容