iOS屏幕适配发展历程
早期 iOS —— frame + autoresizing
直接使用 frame 计算控件的位置
特点:程序中存在大量的
MagicNumber
- iPhone3GS \ iPhone4 \ iPhone4S 屏幕的物理尺寸是一样的(无需屏幕适配)
- 而且一个应用要么是横屏要么是竖屏, 几乎不存在能同时进行横竖屏切换的应用
- 应用程序都是竖屏
- 游戏几乎都是横屏
- 官方应用大多支持横竖屏
使用 autoresizing 进行屏幕适配
- 随着 iPad 的发布, 屏幕物理大小发生了变化
- 并且苹果建议,如果没有特殊原因,在 iPad 上运行的程序如果没有特殊原因,应该支持横竖屏切换
- 因此:不能把控件的 frame 都写死了,需要进行屏幕适配
为了解决屏幕适配需求,苹果同时推出了第一个屏幕适配解决方案:autoresizing
- autoresizing 的核心思想就是:参照父容器来设置子控件的
frame
- 不再写死
frame
, 而是参照父容器 - 举例:在竖屏下有一个按钮要占据整个屏幕宽度, 当切换到横屏下以后同样要占据整个屏幕的宽度
autoresizing
只能设置当前控件与父控件之间的相对关系
iOS 6 —— autolayout(自动布局)
- 随着 iPhone5 \ iPhone5s 等的发布苹果设备不同尺寸的屏幕变得越来越多, 不仅要求能根据控件父子关系来设置相对位置,也要求能根据任意控件之间的关系来设置位置
- 因为 autoresizing 只能设置当前控件与父控件之间的相对关系,当遇到要设置兄弟控件之间的关系的时候 autoresizing 就无能为力了
- autolayout 技术主要解决的问题:控件位置的参照关系不再局限于父控件
iOS 8 —— size classes + autolayout
- 使用 size classes + autolayout 进行屏幕适配
- 当 iPhone6 发布以后,苹果设备的屏幕越来越多(以后也可能出现更多不同大小的屏幕),为了能更容易的适配不同的屏幕,苹果推出了
size classes
技术 - 通过
autolayout
设置的约束,约束一旦添加就会应用于各种屏幕(也就是说在各种不同的屏幕下都使用相同的约束) - 通过 size classes + autolayout 的方式, 可以为不同尺寸的屏幕设置不同的约束举例: iPhone 下的计算器,在横屏、竖屏下的不同表现
- size classes 技术主要解决的问题: 为不同尺寸的屏幕, 通过 autolayout 设置不同的约束
iOS 9 —— size classes + autolayout + StackView
- Stack View 的核心便是方便
垂直
或水平
排布多个 subview - 类似于 android 的
LinearLayout
- Stack View 最有用的就是它会自动为每个 subview 创建和添加 Auto Layout 约束,程序员可以
- 通过选项配置subview的大小、排布以及彼此间的间距
使用 stackview 主要简化在线性方向上,重复设置控件布局约束的问题
- 通过选项配置subview的大小、排布以及彼此间的间距
小结
- 通过代码计算 frame,没有屏幕适配
-
Autoresizing
- 设置控件与父控件的相对关系,从而实现间接设置frame
- iOS 系统在运行时会根据设置的规则,间接计算出对应的 frame,无需手动计算frame
- 通过设置子控件与父控件的关系来决定如何显示控件
-
Autolayout
- 通过设置某控件与任意其他控件间的关系来决定如何显示这个控件
- 不再仅仅局限与父子控件
- 是 iOS 程序员必须掌握的技术
- Interface Builder
- 纯代码
- 框架 Masonry(OC) + SnapKit(Swift)
-
size classes
- 解决在一个正方形的界面上同时设置
任意设备
的自动布局 - 用 Interface Builder 设置比较方便,但是纯代码写起来会比较繁琐
- 解决在一个正方形的界面上同时设置
-
StackView
- 解决线性方向上控件布局
- 是对自动布局的简化
注意
-
无论是通过
autoresizing
还是autolayout
其实只是间接设置了控件的 frame- 所以一旦使用了
autoreszing
或者autolayout
那么就不要在直接设置 frame 了,否者可能产生混乱 - 所有的控件的 frame 由底层
布局系统
计算完成
- 所以一旦使用了
-
autoresizing
和autolayout
二者是互斥的,同时只能使用其中一种- 当使用
autoresizing
的时候无法使用autolayout
- 当使用
autolayout
的时候必须禁用autoresizing
- 当使用
在
Interface Builder
中默认开启自动布局在代码中,默认支持
autoresizing