說實話,對於一個剛入門iOS兩個月的新手而言,在拿到這個任務的時候整個人都是懵逼的,怎么做適配?哪些地方需要適配?該怎么做?一個個問題搞得頭都大了。
首先,啥都不管,先在iPhone X上運行起來看看效果在說,運行之后出現的問題主要有如下幾個:
- 屏幕尺寸還是6S上的尺寸大小,用 [[UIScreen mainScreen] bounds] 打印log確實如此
- 自定義的導航欄的返回按鈕右移明顯
- UISearchBar的高度有變化,而且點擊之后背景顏色和原先不一致
- UITableview的header高度變大,有的地方會出現空白cell格
- UITableview出現的位置不對
- 某些控件的相對位置不對
粗略發現這些變化問題之后,思考一下,主要問題分為兩類:一是iPhone X的屏幕尺寸變化帶來的變化,二是iOS 11新特性引起的問題。iPhone X屏幕尺寸的變化主要出現在屏幕的頭部和底部,頭部設置了導航欄,基本沒有出現什么問題,尾部主要就是某些控件的位置出現變化,可能是因為設置的相對位置是相對view的mas_bottom設置的(項目中是純代碼布局,使用AutoLayout框架Masonry進行布局),這一塊的問題很少,也很簡單,改變一下相對位置的值看看效果就ok。那么剩下的問題應該就是因為iOS 11新特性的問題。因此,首先我們就需要好好研究一下iOS 11有那些新特性,在項目中會出現什么樣的變化呢?
了解iOS 11新特性的方法很多,網上也有很多解析的博客文檔,但是最直接最准確的學習方法就是看官方文檔:Human Interface Guidelines ,這個文檔中介紹了iOS 11的新特性,還有iPhone X的變化和特點都有所介紹,大家可以參考一下,下面我主要列舉一下跟界面相關的新特性,jut8大家也可以參考下面的一些博客的分析鏈接:
- 導航欄變化,大號字體的變化,iOS 11之前的導航欄高度是64px,其中狀態欄的高度是20px,iOS 11中狀態欄的蓋度是44px。
- 底部tabBar的高度變化,iOS 11中底部tabBar的高度由之前的49px變為83px,增高了34px。
- 提出了safeArea的概念,新概念。
關於iPhone X、iOS 11 、Xcode9,我們應該知道這些
了解完iOS 11的新特性之后,接着就分析上面出現的問題的原因與適配方法。
- 屏幕尺寸還是6S上的尺寸大小,用[[UIScreen mainScreen] bounds]打印log確實如此
這個的主要問題就在於沒有適配iPhone X的啟動頁,如果你的項目中沒有自定義的啟動頁則無所謂,否則要進行適配。設置方法是選中Images.xcassets中的LaunchImage,右邊選中圖片右上角紅框中iOS8.0 and later下面的勾,然后就會出現圖片左上角紅框內關於iPhone X的啟動頁的空白框。然后將切好的iPhone X的啟動頁的圖(這個圖要先放進Images.xcassets中)拖進圖片左上角箭頭所指的框中就可以了。By the way,啟動頁的圖的大小一般是按照iPhone X的大小來切,具體尺寸在上面提到的官網有說到,就是:1125px × 2436px (375pt × 812pt @3x),如果還有導航頁、廣告頁也基本上都可以按照這個尺寸來切圖。

2. 自定義的導航欄的返回按鈕右移明顯
iOS 11改動相當大的就是導航欄的部分,除了新加入了largeTitles和searchController兩個新特性,還對導航欄的圖層結構進行了調整,在原來的已經復雜的不要的圖層中又新增了新的圖層!是的你沒有看錯,_UINavigationBarContentView和_UIButtonBarStackView和_UITAMICAdaptorView 而我們之前的leftBarButtonItem什么的現在都在UIButtonBarStackView中了。

1 <_UIButtonBarStackView: 0x7ff988074290; frame = (12 0; 48 44); layer = <CALayer: 0x60000042bc80>> 2 Printing description of $11: 3 <UIView: 0x7ff9880764a0; frame = (0 22; 8 0); layer = <CALayer: 0x60000042b7c0>> 4 Printing description of $12: 5 <_UITAMICAdaptorView: 0x7ff988076790; frame = (8 2; 40 40); autoresizesSubviews = NO; layer = <CALayer: 0x60000042b8a0>>
我們可以看到一個_UIButtonBarStackView占掉了12個像素的左邊約束,_UITAMICAdaptorView又占據了8個像素的左邊約束,所以說我們很無語的就被占據了20px,更可氣的是,都是私有對象,不容易修改!這也就是為什么我們的返回鍵的位置會右移的原因了。
為了解決這一問題,直接通過 self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView: backButton]; 將自定義的按鈕Button賦值給self.navigationItem.leftBarButtonItem,則其而位置由系統確定,則會出現上面的右移的情況。我們知道,Button中其實是由一個UIImage和一個UILabel組成的,然后我們可以通過contentEdgeInsets、imageEdgeInsets、titleEdgeInsets來設置button本身、button中的圖片以及button中的label的相對位置,這個相對位置是相對初始位置而言的,所以我們這里只需要對自定義的button進行這三個值的設定就可以解決按鈕右移的問題了,具體向左偏移量可以自己設置。效果圖如下圖所示,左邊是修復前,右邊是修復后的圖。
1 //自定義button按鈕 2 CLBackButton *backButton = [CLBackButton createBackButtnWithPopVc:returnTitle]; 3 4 //ios11 返回按鈕右移 適配 5 if (@available(iOS 11.0, *)) { 6 backButton.contentEdgeInsets = UIEdgeInsetsMake(0, -15,0, 0); 7 backButton.imageEdgeInsets = UIEdgeInsetsMake(0, -15,0, 0); 8 backButton.titleEdgeInsets = UIEdgeInsetsMake(0, -10,0, 0); 9 } 10 11 //將自定義的按鈕添加到返回鍵上 12 self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView: backButton];

3. UISearchBar的高度有變化,而且點擊之后背景顏色和原先不一致

上圖右邊圖是點擊搜索框之前和點擊結束輸入后正常情況下的效果,左邊圖是iOS 11下點擊點擊結束輸入后的效果。因為在這里項目中並沒有對搜索欄進行自定義或者修改參數,但是iPhone X的自帶系統軟件中搜索點擊之后很正常,所以猜測很可能是默認布局的一些參數被修改了。參看項目源代碼,發現我們對setExtendedLayoutIncludesOpaqueBars進行了設置為YES。這個參數的設置會有什么影響呢?ExtendedLayoutIncludesOpaqueBars參數的含義是不透明的導航欄條下是否可以擴展,默認是NO,如果設為YES,則表示可以擴展,即可能會受到導航欄的影響,我們知道在iOS 11中導航欄的變化非常大。所以試了一下將其設置為NO之后的效果,還真是。。。適配代碼如下:
1 //適配iOS 11的搜索欄點擊之后顏色變化問題 2 if (@available(iOS 11.0, *)) { 3 [self setExtendedLayoutIncludesOpaqueBars:NO]; 4 }else{ 5 [self setExtendedLayoutIncludesOpaqueBars:YES]; 6 }
雖然問題解決了,但是歲這個參數還是了解不夠,后面自己查了一些資料,覺得這一篇博客寫的比較直觀,感興趣的可以看下:與導航欄下控件的frame相關的edgesForExtendedLayout、translucent、extendedLayoutIncludesOpaqueBars、automaticallyAdjustsScrollViewInsets等幾個屬性的詳解
4. UITableview的header高度變大,有的地方會出現空白cell格
iOS 11中對UITableview的改變也是蠻大的,原本的automaticallyAdjustsScrollViewInsets竟然過期了,在IOS 11下 APPLE推薦使用UIScrollView的contentInsetAdjustmentBehavior屬性進行設置自動計算滾動視圖的內容邊距。 並且在iOS 11中如果沒有重寫header、footer的height和view函數,iOS 11中系統不會像之前那樣自動調用。所以出現空白cell格的原因應該就是缺少footer的height和view函數,加上就沒什么問題了。這個就不放圖了,很簡單
5. UITableview出現的位置不對
和問題4中的問題一樣,都是UITableview的問題,主要原因還是iOS 11中automaticallyAdjustsScrollViewInsets過期了,加上導航欄的高度的變化和safeArea的概念的提出,使得UITableview在iOS 11的布局上會出現一些偏差,因為涉及到項目信息,所以就不放圖了。解決方案如下
1 //ios11 tableview 適配 2 if (@available(iOS 11.0, *)) { 3 if ([self.tableView respondsToSelector:@selector(setContentInsetAdjustmentBehavior:)]) { 4 self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; 5 } 6 }
