iOS開發(fā)·適配iPhone X相關(guān)的宏和方法
過了好久,今天終于有時間總結(jié)一下適配iPhone X相關(guān)的坑,總的來說有兩類坑,一個是導(dǎo)航欄+狀態(tài)欄的高度發(fā)生了變化,一個是一些沒有實現(xiàn)實現(xiàn)-tableView: viewForHeaderInSection:和-tableView: viewForFooterInSection:等代理方法的UITableView會出錯位的問題。

1. 判斷是否iPhone X:返回YES或NO
1.1 判斷:宏
(1)依據(jù)屏幕分辨率
三目運算法
- //是否iPhoneX YES:iPhoneX屏幕 NO:傳統(tǒng)屏幕
- #define kIs_iPhoneX ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size) : NO)
多行邏輯判斷
- //是否iPhoneX 1:iPhoneX屏幕 0:傳統(tǒng)屏幕
- #define kIs_iPhoneX_test ({\
- int tmp = 0;\
- if ([UIScreen instancesRespondToSelector:@selector(currentMode)]) {\
- if (CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size)) {\
- tmp = 1;\
- }else{\
- tmp = 0;\
- }\
- }else{\
- tmp = 0;\
- }\
- tmp;\
- })
其中,反斜杠\并不是注釋或者其它的無用符號,其實是多行宏換行必須要用的標(biāo)志。
***一句tmp;\也是必須的,因為要將經(jīng)過邏輯判斷得到的tmp作為該宏的返回值。
(2)依據(jù)屏幕尺寸
- #define kIs_iPhoneX (kSCREEN_WIDTH == 375.f && kSCREEN_HEIGHT == 812.f)
- #define kSCREEN_WIDTH ([UIScreen mainScreen].bounds.size.width)
- #define kSCREEN_HEIGHT ([UIScreen mainScreen].bounds.size.height)
1.2 判斷:方法
方法:依據(jù)設(shè)備型號
- +(BOOL)getIs_iPhoneX{
- struct utsname systemInfo;
- uname(&systemInfo);
- NSString *platform = [NSString stringWithCString: systemInfo.machine encoding:NSASCIIStringEncoding];
- if([platform isEqualToString:@"iPhone10,3"]||[platform isEqualToString:@"iPhone10,6"]) {
- return YES;
- }else{
- return NO;
- }
- }
2. 靈活返回狀態(tài)欄+導(dǎo)航欄的高度
需求:靈活得到導(dǎo)航欄+狀態(tài)欄的高度,作為一個子視圖Y軸的起點。
宏定義
- #define kStatusBarAndNavigationBarHeight (kIs_iPhoneX ? 88.f : 64.f)
調(diào)用范例
- //自動適配
- _segmentedControl.frame = CGRectMake(0, kStatusBarAndNavigationBarHeight, kSCREEN_WIDTH, 55);
3. 拓展:獲得iOS系統(tǒng)與App版本信息
獲取iOS系統(tǒng)版本號:返回字符串
- + (NSString *)getSystemVersion{
- return [[UIDevice currentDevice] systemVersion];
- }
獲取App版本號:返回字符串
- + (NSString *)getAppVersion{
- NSDictionary *infoDic = [[NSBundle mainBundle] infoDictionary];
- // 獲取App的版本號
- NSString *appVersion = [infoDic objectForKey:@"CFBundleShortVersionString"];
- return appVersion;
- }
4. 適配iPhone X的其他問題
適配iPhone X和Xcode 9的過程中,除了與導(dǎo)航欄相關(guān)的問題,還有一個問題經(jīng)常出現(xiàn),就是UITableView相關(guān)的問題。下面兩個辦法可以解決多數(shù)錯位的問題。
VC創(chuàng)建tableView屬性的時候這樣設(shè)置
- self.tableView.estimatedRowHeight = 0;
- self.tableView.estimatedSectionHeaderHeight = 0;
- self.tableView.estimatedSectionFooterHeight = 0;
還可以這樣設(shè)置
- //cell自適應(yīng)高度
- self.tableView.rowHeight = UITableViewAutomaticDimension;
- //預(yù)估行高
- self.tableView.estimatedRowHeight = 44.0f;
關(guān)于根視圖的安全區(qū)
iOS新增了個safeArea,原來的老代碼中,規(guī)定子視圖跟根子視圖的關(guān)系的代碼需要新增一個判斷:當(dāng)iOS 11時,需要改為子視圖跟根子視圖的安全區(qū)的關(guān)系。這樣就不會在iPhone X的底部虛擬home有任何控件干擾了。
- if (@available(iOS 11.0, *)) {
- make.edges.equalTo(self.view.safeAreaInsets)
- } else {
- make.edges.equalTo(self.view)
- }
當(dāng)然,一般除了tabbar不能放在這個底部虛擬home區(qū),其它的視圖tableView視圖或者網(wǎng)頁視圖時可以放在底部虛擬home區(qū)中的。這時候,不需要強調(diào)必須把子視圖放在safeArea之內(nèi),原來的老代碼也就不用改。