[iOS开发]一个实例带你搞懂size classes
1. 什么是Size Classes
Size Classes 是多组应用于区分屏幕宽度和高度的一种分类, 当前有2 种Size Classes: Compact和 Regular.
- 苹果手机竖屏(Portrait)模式下, 高都是regular height, 宽都是compact width.
- 苹果手机横屏(Landscape)模式下, 高都是compact height, 非plus/Max手机宽都是compact width, plus/max 手机宽都是regular width.
在 Storyboard 中, 一般用简写的 C 表示 Compact, R 表示 Regular.例如wC表示Compact Width, hR表示 Regular Height. 这样的话屏幕的长和就一共可能有 4 种组合.
- wC + wR
- wC + hR
- hC + wR
- hC + hR
具体手机的 Size Classes 是如何分类的详见下表:

注意, 有些手机例如iPhone 11 Pro竖屏下是 compact width + regular height, 但是横屏下width 并不是 regular: 而是compact width + compact height. 注意这里的区别.
那么在实际开发中如何使用这个 Size Classes 呢. 下面我通过一个具体的实例来介绍 Size Classes 的用法
2. Size Classes 实例讲解.
2.1 需求
假设我们需要实现一个很简单的页面. 在竖屏和横屏模式下分别显示如下:
-
首先我们创建一个项目, 拖入一个 UIImageView 和 UILabelView.设置好图片.竖屏(Portrait)下的Constraints设置很简单, 不做赘述. 截图如下.
ImageView设置
Label设置
运行后可以看到竖屏下,满足要求. 横屏下不满足要求
下面看看如何通过Size Classes修改横屏View 的排列.
那么在 Size Classes 中我们要如何区分横屏和竖屏呢? 他们的Size Classes区别是什么呢?
从上面的 Excel 表中可以看出, 横屏和竖屏的区别高度Height, 所有手机在竖屏模式下的高都是Regular Height即hR;所有手机在横屏模式下都是Compact Height即hC. 区别知道了,那么现在开始搞
在 Storyboard 中选中"Orientation", 然后点击"Vary for Traits"

注意: 因为我们用 Height 来区分横屏和竖屏,所以选中"Height". 我最开始也很纠结, 这里的Width和 Height 我究竟应该选择哪个呢? 其实这里的Width和 Height 是根据你左侧选择的设备来的, 例如我现在选择的是iPhone 12 Pro Max, 它在横屏模式下就是Regular Width 和Compact Height. 在"Vary canvas edits for"中如果只选择了"Height",那么后面所有的关于 Constraints 的修改都是基于Compact Height 屏幕的手机. 如果只选择了"Width"那么后面的修改都是基于Regular Width的..

如果你还是不清楚是选择 Width还是 Height, 那么也没有关系, 你可以试着选一个看看, 它会显示你当前选择的是哪种 size class. 例如如果此时你选择了 Height, 下面会显示如下:

这时候你可以看见那个 Size Classes 栏为蓝色背景, 同时显示"Varing xx Compact Height Devices"表示后面的Constraints操作都是针对当前Compact Height这个Size Class的.
再回头看我上面的那个 excel 表格, Compact Height正好可以区分 iPhone 的横屏和竖屏. 但是不可以用Compact Width区分横屏和竖屏, 原因就是上面我说过的: 有几种型号例如iPhone 11 Pro无论是在横屏还是竖屏下, width都是 compact width.
然后选中图片 UIImageView, 在右边Size Inspector中找到与之相关的约束Constraints, 这些 Constraints 是缺省的约束, 不适合横屏,所以要按Delete 键统统删除.

注意, 这里的删除只是从当前Compact Height这个 Size Class删除了, 并不会影响竖屏模式下的约束.
如此这般, 将 UILabel 中的约束也统统删除, 一个都不要. 所有约束删完后应该显示这样:

Constraints删除后, 在Size Inspector栏中已经看不见约束了, 但是你仍然可以从左边的控件导航栏中看到刚刚删除的Constraints, 并且当前他们显示为灰色, 表示这些Constraints在当前 Size Classe 下不生效.
不要担心上面显示的小红点, 我们现在就修复它.
将 Storyboard 中的 Image和 Label 拖动到理想中的位置, 然后根据需求设置好Constraints, UIImageView的设置如下

UILabel的Constraints 设置如下

至此, 全部设置完, 你应该可以看到上面的 红点消失了, 说明我们 Constraints 设置正确. 单击"Done Varying" 完成 Constraints 设置
再次运行项目, 旋转屏幕, 可以看到横屏 Landsca 模式下实际运行效果与需求一致. 完美

本示例项目可以在 Github 上下载