過(guò)了好久独悴,今天終于有時(shí)間總結(jié)一下適配iPhone X相關(guān)的坑述吸,總的來(lái)說(shuō)有兩類(lèi)坑盏求,一個(gè)是導(dǎo)航欄+狀態(tài)欄的高度發(fā)生了變化噪漾,一個(gè)是一些沒(méi)有實(shí)現(xiàn)實(shí)現(xiàn)
-tableView: viewForHeaderInSection:
和-tableView: viewForFooterInSection:
等代理方法的UITableView會(huì)出錯(cuò)位的問(wèn)題充活。
1. 判斷是否iPhone X:返回YES或NO
1.1 判斷:宏
(1)依據(jù)屏幕分辨率
- 三目運(yùn)算法
//是否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;\
})
- 其中蜂莉,反斜杠
\
并不是注釋或者其它的無(wú)用符號(hào)蜡娶,其實(shí)是多行宏換行必須要用的標(biāo)志。- 最后一句
tmp;\
也是必須的映穗,因?yàn)橐獙⒔?jīng)過(guò)邏輯判斷得到的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è)備型號(hào)
+(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)欄的高度,作為一個(gè)子視圖Y軸的起點(diǎn)蚁滋。
- 宏定義
#define kStatusBarAndNavigationBarHeight (kIs_iPhoneX ? 88.f : 64.f)
- 調(diào)用范例
//自動(dòng)適配
_segmentedControl.frame = CGRectMake(0, kStatusBarAndNavigationBarHeight, kSCREEN_WIDTH, 55);
3. 拓展:獲得iOS系統(tǒng)與App版本信息
- 獲取iOS系統(tǒng)版本號(hào):返回字符串
+ (NSString *)getSystemVersion{
return [[UIDevice currentDevice] systemVersion];
}
- 獲取App版本號(hào):返回字符串
+ (NSString *)getAppVersion{
NSDictionary *infoDic = [[NSBundle mainBundle] infoDictionary];
// 獲取App的版本號(hào)
NSString *appVersion = [infoDic objectForKey:@"CFBundleShortVersionString"];
return appVersion;
}
4. 適配iPhone X的其他問(wèn)題
適配iPhone X和Xcode 9的過(guò)程中宿接,除了與導(dǎo)航欄相關(guān)的問(wèn)題,還有一個(gè)問(wèn)題經(jīng)常出現(xiàn)辕录,就是UITableView相關(guān)的問(wèn)題睦霎。下面兩個(gè)辦法可以解決多數(shù)錯(cuò)位的問(wèn)題。
- VC創(chuàng)建tableView屬性的時(shí)候這樣設(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新增了個(gè)safeArea走诞,原來(lái)的老代碼中副女,規(guī)定子視圖跟根子視圖的關(guān)系的代碼需要新增一個(gè)判斷:當(dāng)iOS 11時(shí),需要改為子視圖跟根子視圖的安全區(qū)的關(guān)系蚣旱。這樣就不會(huì)在iPhone X的底部虛擬home有任何控件干擾了碑幅。
if (@available(iOS 11.0, *)) {
make.edges.equalTo(self.view.safeAreaInsets)
} else {
make.edges.equalTo(self.view)
}
當(dāng)然,一般除了tabbar不能放在這個(gè)底部虛擬home區(qū)塞绿,其它的視圖tableView視圖或者網(wǎng)頁(yè)視圖時(shí)可以放在底部虛擬home區(qū)中的沟涨。這時(shí)候,不需要強(qiáng)調(diào)必須把子視圖放在safeArea之內(nèi)位隶,原來(lái)的老代碼也就不用改拷窜。