/ 多端适配 iPad/iPhone md 版 /
1
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
不过,苹果还提供了其他更多更丰富的适配工具:
1.1
auto layout 多屏适配
Auto Layout 是 storyboard 里面的一个子属功能,用来进行多屏适配用的。它的主要功能是可以通过你设置的 constraints ,来动态设置 View 的 position 和 size ,达到动态适配的效果。
其中设置多屏的关键点,首先在于如何区分多屏。目前,IOS 提供了 trait 的环境变量,用来指明当前屏幕的横竖和比例关系。trait 是用来描述屏幕大小、横竖屏的一个概念集合。
还记得,在 Xcode 工具栏中,有一行指明了当前的机型和屏幕:
其中 C 代表 compact;R 代表 regular。这两个属性是用来描述屏幕短边和长边的特征。例如:
在实际代码中,你可以直接通过 traitCollection 去获取对应的 horizontalSizeClass 和 verticalSizeClass 属性,然后通过对比值来进行判断。
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;
}
1.2
StackView 适配
苹果提供一个简便的自适应容器 StackView,有点类似 CSS 中的 flex 布局属性,你可以很容易构建一个水平或者垂直的流式布局。它最大的一个特点是会自动为里面的 UIView 构建布局约束。
UIStackView 拥有三个规则 分布方向、对齐规则、分布规则,优先指定 axis 属性,来定义布局轴的方向。这个属性的特点就是很适合用在 横竖屏切换上使用,按照 iphone 的 wRhC(横屏)、wChR(竖屏) 的 trait 设置不同的 constraint,可以得到响应式适配的效果:
1.3
IOS multitask(splitview) 适配
IOS multitask 是 iPad 提供给 app 进行多窗口交互的一个特性,这个特性可以极大增加办公效率,不需要频繁切换 app 运行。当然,更多的时候,也是对宽屏下, app 运行的一个补充。
参考:如何在 IOS 使用 multitask ( https://support.apple.com/en-us/HT207582 )
默认情况下,我们在 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 时,排布只会有:
而对于两个 app 默认的 trait 都是 wChR,也就是常规 iPhone 的交互比例大小。
Horizontal 分屏当 iPad 处于横屏时,整体的宽度被拉长了,所以分屏的选择性就多了一个 等分, 1:1。现在 iPad 在横屏下的分屏就有 1:2 和 1:1 两种排列。同样,假设有两个 app, A、B,两者的排布方式就有:
在非 iPad Pro 上,两个 app 屏幕 trait 的表达如下:
但是,在 iPad Pro 上,等比排布时,会有区分:
参考文献: