11月9日更----八.Home Indicator
===========================
10月25日更,增加iPhone X需要適配的尺寸的宏定義----六--1
====================================
一.APP在iPhoneX運(yùn)行后不能占滿屏幕,上下都有多余的邊
解決方法:把舊的image.xcassets中的LaunchImage刪掉,重新創(chuàng)建并在Images.xcassets中為iPhone X添加一個(gè)LaunchImage,新的啟動(dòng)圖尺寸為1125px × 2436px(375pt × 812pt @3x).

問題原因:1.應(yīng)用啟動(dòng)后的顯示尺寸會(huì)根據(jù)啟動(dòng)圖的大小來顯示,因?yàn)榕f的工程沒有iPhoneX的尺寸,所以就會(huì)出現(xiàn)上下有多余邊的問題.
2.舊工程工程的xcassets沒有iPhoneX,所以需要把舊的刪掉,重新創(chuàng)建,才可以添加iPhoneX尺寸的啟動(dòng)
二.局部適配
因?yàn)閕PhoneX的屏幕上下邊角是有弧度的,如果沒有適配弧度外是看不到的
iOS11 以前,我們布局時(shí),視圖的 top 和 bottom 一般參照的是 Top Layout Guide 和 Bottom Layout Guide
iOS11 以后,那兩個(gè)參照已經(jīng) deprecated (過時(shí))了,而被 Safe Area 取代。
Safe Area 要求最低支持 iOS9.0
最后總結(jié)SafeArea
三.titleview適配

很多APP都會(huì)在navigation的titleview上添加搜索框,在iOS11上回出現(xiàn)這種情況的偏移
解決方法:
在替換titleview的view里實(shí)現(xiàn)方法:
- (CGSize)intrinsicContentSize {
return UILayoutFittingExpandedSize;
}
四.適配下拉刷新

下拉在正常狀態(tài)下會(huì)有尺寸偏移
解決方法1:在controller中添加
if (@available(iOS 11.0, *)) {
self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
} else {
self.automaticallyAdjustsScrollViewInsets = NO;
}
解決方法2:
self.automaticallyAdjustsScrollViewInsets = NO;
self.extendedLayoutIncludesOpaqueBars = YES;
self.edgesForExtendedLayout = UIRectEdgeTop;
問題原因:多數(shù)情況是在隱藏導(dǎo)航欄出現(xiàn)的,因?yàn)閕OS11后tableview的automaticallyAdjustsScrollViewInsets屬性被廢棄了,頂部就多了一定的inset,也可能是SafeArea(安全區(qū)域)的原因,關(guān)于SafeArea(安全區(qū)域)適配下邊會(huì)寫.
如果還是有尺寸偏移那就是tableview的另一個(gè)解決方法,看下邊
五.tableview間隙問題
解決方法:實(shí)現(xiàn)-tableView: viewForFooterInSection: 和 -tableView: viewForHeaderInSection:方法.或者設(shè)置tableview的estimatedRowHeight estimatedSectionHeaderHeight estimatedSectionFooterHeight三個(gè)屬性為0
問題原因:iOS 11中如果不實(shí)現(xiàn)-tableView: viewForFooterInSection: 和 -tableView: viewForHeaderInSection:,那么-tableView: heightForHeaderInSection:和- tableView: heightForFooterInSection:不會(huì)被調(diào)用。
這是因?yàn)樵趖ableview中的 estimatedRowHeight estimatedSectionHeaderHeight estimatedSectionFooterHeight三個(gè)高度估算屬性由默認(rèn)的0變成了UITableViewAutomaticDimension,導(dǎo)致高度計(jì)算不對。
六.SafeArea適配

1.官方的安全區(qū)域的指導(dǎo)圖,舊的項(xiàng)目運(yùn)行在iPhone X上最大顯著的問題就是導(dǎo)航和底部tabbar的位置偏移,因?yàn)橹暗膶?dǎo)航高度為64,隨意程序基本都寫的死值,適配的話就各種苦逼了,xib和代碼的各有各的哭,總之所有的地都要通過判斷是否是iPhoneX來適配高度.
為了適配我添加了全局的宏
//是否是iPhone X
#define is_iPhoneX ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size) : NO)
//狀態(tài)欄高度
#define StatusBarHeight (is_iPhoneX ? 44.f : 20.f)
// 導(dǎo)航高度
#define NavigationBarHeight 44.f
// Tabbar高度. 49 + 34 = 83
#define TabbarHeight (is_iPhoneX ? 83.f : 49.f)
// Tabbar安全區(qū)域底部間隙
#define TabbarSafeBottomMargin (is_iPhoneX ? 34.f : 0.f)
// 狀態(tài)欄和導(dǎo)航高度
#define StatusBarAndNavigationBarHeight (is_iPhoneX ? 88.f : 64.f)
#define ViewSafeAreInsets(view) ({UIEdgeInsets insets; if(@available(iOS 11.0, *)) {insets = view.safeAreaInsets;} else {insets = UIEdgeInsetsZero;} insets;})
2.在Storyboard中有SafeArea的選項(xiàng),但是只支持iOS9以上,你的老板肯定是不會(huì)同意的,所以慢慢改吧.
3.如果使用了Masonry 進(jìn)行布局,就要適配safeArea
if (@available(iOS 11.0, *)) {
make.edges.equalTo(self.view.safeAreaInsets);
} else {
make.edges.equalTo(self.view);
}
4.在沒有適配的頁面底部是到屏幕低的,需要設(shè)置到安全區(qū)域內(nèi),把底部的黑條留出來.
比如天貓的適配:

七.UIImagePickerController 設(shè)置導(dǎo)航背景圖
[self.navigationBar setBackgroundImage:[UIImage imageNamed:@"navBg"] forBarMetrics:UIBarMetricsDefault];
這樣設(shè)置發(fā)現(xiàn)對 UIImagePickerController 不起作用,需要使用:
self.navigationBar.barTintColor = [UIColor blackColor];
八.Home Indicator
Home indicator 的設(shè)置類似于 prefersStatusBarStyle,iOS 11 增加了 UIViewController 的一個(gè) UIHomeIndicatorAutoHidden 分類來控制 home 鍵的自動(dòng)隱藏。通常在全屏播放視頻,全屏游戲等場景下會(huì)需要用到此特性。
@interface UIViewController (UIHomeIndicatorAutoHidden)
// Override to return a child view controller or nil. If non-nil, that view controller's home indicator auto-hiding will be used. If nil, self is used. Whenever the return value changes, -setNeedsHomeIndicatorAutoHiddenUpdate should be called.
- (nullable UIViewController *)childViewControllerForHomeIndicatorAutoHidden API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos);
// Controls the application's preferred home indicator auto-hiding when this view controller is shown.
- (BOOL)prefersHomeIndicatorAutoHidden API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos);
// This should be called whenever the return values for the view controller's home indicator auto-hiding have changed.
- (void)setNeedsUpdateOfHomeIndicatorAutoHidden API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos);
@end
蘋果并沒有提供可以手動(dòng)改變 home indicator 顏色的接口給開發(fā)者。因?yàn)樘O果并不希望我們手動(dòng)更改 home indicator 的顏色,而應(yīng)該遵循其自動(dòng)切換顏色的特性(Home indicator 會(huì)根據(jù)底色的不同自動(dòng)切換黑色或白色)。