一、Size class
什么是Size Classes?
size classes也是出現(xiàn)在iOS8的功能,.xib文件也是可以使用的,但大部分情況還是基于SB來使用,從xcode6開始我們新建的xib或SB文件中對應的View下方顯示wAny hAny,點擊后發(fā)現(xiàn)是可以選擇的,選擇不同的情況,View又變成了不同的形狀,這就是size classes。
也可以這么理解,size classes就是對設(shè)備的屏幕尺寸進行了抽象,寬高都分別用Regular、Compact來表示,我們其實不用太在意名稱,只知道,以后不同的設(shè)備或者不同的狀態(tài)(橫豎屏)可以由這種描述來表示即可。
更多參考。:http://www.itdecent.cn/p/576f9971e2cc
Device size classes

二、 Vary Constraints In Xcode 13
Xcode的文檔好像還沒有跟上,但答案似乎是回到創(chuàng)建約束的Installed屬性的變化。你會在尺寸檢查器中發(fā)現(xiàn):

實際的例子
如果我們需要將一個藍色的View,在橫豎屏情況下有不同的布局顯示。如下圖所示:一個在豎屏情況下居中顯示,一個在橫屏情況下左上角顯示。

分析一下:iphone豎屏情況下,所有的機型的size classes都是: width-Compact, height-Regular,所以我們只需要在width-Compact, height-Regular的條件下設(shè)置約束就好。而iPhone橫屏情況下,一部分的機型是width-Compact, height-Compact,一部分機型是width-Regular, height-Compact,綜合一下就是width-Any,height-Compact的條件下設(shè)置約束就可以。
接下來我們用xcode13來構(gòu)建約束吧!
1、首先按常規(guī)的操作,用Xib設(shè)置好約束。

2、勾掉右邊的install
展開左側(cè)欄的約束,分別選中對應約束,勾選掉installed

默認的installed被勾選,意思就是約束對所有的size classes約束都生效,所以為了實現(xiàn)最初的需求,我們首先把View.centerX=centerX,View.centY=centerY的installed,因為我們的需求并不區(qū)分大小,所以height=200,width=200的installed就不需要勾選3、添加你需要的installed
選中相應的約束,點擊右側(cè)的+號

選擇Width-Compact,Height-Regular之后,Add Variation。并勾選wC hR installed。


做完以上的設(shè)置,我們已經(jīng)完成了對豎屏下的布局約束,接下來繼續(xù)對橫屏下的布局約束進行設(shè)置
4、設(shè)置橫屏
旋轉(zhuǎn)之xib面板為橫屏,然后按照重復之前的操作,添加Width-Any,Height-Compact installed


三、UITraitCollection
UITraitCollection為表征 size class 而生,用來區(qū)分設(shè)備。你可以在它身上獲取到足以區(qū)分所有設(shè)備的特征。
@protocol UITraitEnvironment <NSObject>
@property (nonatomic, readonly) UITraitCollection *traitCollection
NSLog(@"%@",self.traitCollection);
控制臺打印:
<UITraitCollection: 0x600002a27d40; UserInterfaceIdiom = Phone, DisplayScale = 2, DisplayGamut = P3, HorizontalSizeClass = Compact, VerticalSizeClass = Regular, UserInterfaceStyle = Light, UserInterfaceLayoutDirection = LTR, ForceTouchCapability = Unavailable, PreferredContentSizeCategory = L, AccessibilityContrast = Normal, UserInterfaceLevel = Base>
if (self.traitCollection.horizontalSizeClass==UIUserInterfaceSizeClassCompact&&self.traitCollection.verticalSizeClass==UIUserInterfaceSizeClassRegular&&self.traitCollection.userInterfaceIdiom == UIUserInterfaceIdiomPhone) {
NSLog(@"豎屏");
}else{
NSLog(@"橫屏");
}
可以通過子類重寫如下方法的方式監(jiān)控 traitCollection 屬性的變化
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
[super traitCollectionDidChange:previousTraitCollection];
if (@available(iOS 12.0, *)) {
if(self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleLight){
NSLog(@"淺色模式");
}else if (self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark){
NSLog(@"深色模式");
}
} else {
}
}