iOS開發(fā)·適配iPhone X相關的宏和方法
過了好久,今天終于有時間總結一下適配iPhone X相關的坑,總的來說有兩類坑,一個是導航欄+狀態(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;\
 - })
 
其中,反斜杠\并不是注釋或者其它的無用符號,其實是多行宏換行必須要用的標志。
***一句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ù)設備型號
- +(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)欄+導航欄的高度
需求:靈活得到導航欄+狀態(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的過程中,除了與導航欄相關的問題,還有一個問題經(jīng)常出現(xiàn),就是UITableView相關的問題。下面兩個辦法可以解決多數(shù)錯位的問題。
VC創(chuàng)建tableView屬性的時候這樣設置
- self.tableView.estimatedRowHeight = 0;
 - self.tableView.estimatedSectionHeaderHeight = 0;
 - self.tableView.estimatedSectionFooterHeight = 0;
 
還可以這樣設置
- //cell自適應高度
 - self.tableView.rowHeight = UITableViewAutomaticDimension;
 - //預估行高
 - self.tableView.estimatedRowHeight = 44.0f;
 
關于根視圖的安全區(qū)
iOS新增了個safeArea,原來的老代碼中,規(guī)定子視圖跟根子視圖的關系的代碼需要新增一個判斷:當iOS 11時,需要改為子視圖跟根子視圖的安全區(qū)的關系。這樣就不會在iPhone X的底部虛擬home有任何控件干擾了。
- if (@available(iOS 11.0, *)) {
 - make.edges.equalTo(self.view.safeAreaInsets)
 - } else {
 - make.edges.equalTo(self.view)
 - }
 
當然,一般除了tabbar不能放在這個底部虛擬home區(qū),其它的視圖tableView視圖或者網(wǎng)頁視圖時可以放在底部虛擬home區(qū)中的。這時候,不需要強調(diào)必須把子視圖放在safeArea之內(nèi),原來的老代碼也就不用改。















 
 
 


 
 
 
 