蘋果虐我千百遍炸庞,我待蘋果如初戀。 橫批:iOS開發(fā)苦静陈。
iOS 11系統(tǒng)對于開發(fā)者來說燕雁,變化不算小,各種適配問題接踵而至鲸拥。
本文主要介紹 UINavigationBar 層級結(jié)構(gòu)變化拐格,UIScrollView Layout變化,UISearchBar寬高變化刑赶,引起的問題的原理分析捏浊,著重提出解決方案,還有iPhone X的適配撞叨。附言介紹一下Xcode 9的小Tips金踪。
問題一:
1、導航欄高度變化:
iOS 11添加了大標題牵敷,由系統(tǒng)屬性prefersLargeTitles
決定胡岔,NavigationBar高度如下圖1、2:
總結(jié)來說:如果都用的系統(tǒng)的NavigationBar枷餐,全部無需適配高度靶瘸。但是(忽略LargeTitle部分)如果自定義的NavigationBar,iPhone X之前機型正常height == 64毛肋,對于程序中很多寫死的64怨咪,簡直是福音,無需更改润匙,但對于iPhone X的高度則變成height == 88诗眨,不得不適配≡谢洌可能需要的兩個宏定義:
#define kStatusBarHeight CGRectGetHeight([[UIApplication sharedApplication] statusBarFrame])
#define kNavigationBarHeight CGRectGetHeight([[UIApplication sharedApplication] statusBarFrame]) + CGRectGetHeight(self.navigationController.navigationBar.frame)
2匠楚、導航欄圖層變化
這個實在是搞大事啊。
在iOS11之后厂财,蘋果添加了新的類來管理油啤,navigationBar會添加在_UIButtonBarStackView上面,而_UIButtonBarStackView則添加在_UINavigationBarContentView上面蟀苛;如果沒有給titleView賦值,則titleView會直接添加在_UINavigationBarContentView上面逮诲,如果賦值給了titleView帜平,則會新生成_UITAMICAdaptorView幽告,把titleView添加在這個類上面,這個類會添加在_UINavigationBarContentView上面裆甩,如下圖3冗锁、4:
3、導航欄邊距變化
在iOS 11對導航欄里面的UIBarButtonItem
的邊距也做了調(diào)整:
在iOS 11之前嗤栓,我們可以設(shè)置一個width為負值冻河,類型為UIBarButtonSystemItemFixedSpace
的navigationBarButton,間按鈕擠到屏幕邊緣茉帅,如下圖5:
但是iOS 11叨叙,這招失效啦,原因就在于NavigationBar圖層發(fā)生了變化堪澎,引起了如下圖6的問題:
解決方案:
(1)最簡單粗暴的方式擂错,在每個需要設(shè)置item的VC中,設(shè)置button的setContentEdgeInsets:
樱蛤。
(2)在viewWillAppear
里面钮呀,將_UIButtonBarStackView取出來,直接通過layoutMargins
設(shè)置偏移量昨凡。如下:
//設(shè)置leftBarButtonItem
for (UIView *view in self.navigationController.navigationBar.subviews[2].subviews) {
if ([view isKindOfClass:UIStackView.class]) {
view.layoutMargins = UIEdgeInsetsMake(0, -15, 0, 0);
}
}
(3)同上述方法2的原理爽醋,通過動態(tài)運行時,hock住setLeftBarButtonItem:
和setRightBarButtonItem:
系統(tǒng)方法便脊,創(chuàng)建自定義的View蚂四,在View的layoutSubviews
方法中,找到UIStackView,通過NSLayoutConstraint
調(diào)整該視圖的布局,達到目的镊尺,但是也需要在viewWillAppear
里面重新創(chuàng)建悼做,不然當push到下一級頁面時,再返回姆钉,位置會恢復。
轉(zhuǎn)載大神的Demo地址如下:
https://github.com/spicyShrimp/iOS-11-UINavigationItem-SXFixSpace
(4)完全舍棄系統(tǒng)的Navi,自定義Navi送讲,個人不建議使用,不僅要適配 安全區(qū)域惋啃,如果哪天蘋果Daddy心血來潮哼鬓,又改啦,呵呵边灭。
問題二:滾動視圖的變化
1异希、iOS11棄用了automaticallyAdjustsScrollViewInsets屬性
導致的現(xiàn)象:UITableView列表出現(xiàn)錯位;頁面切換過程中出現(xiàn)抖動問題绒瘦。
解決辦法:
//在基類VC中
if (@available(iOS 11.0, *)) {
[UIScrollView appearance].contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
2称簿、UITableView默認使用Self-Sizing
iOS 11中如果不實現(xiàn)-tableView: viewForFooterInSection: 和 -tableView: viewForHeaderInSection:扣癣,那么-tableView: heightForHeaderInSection:和- tableView: heightForFooterInSection:不會被調(diào)用。
這是因為 estimatedRowHeight憨降、estimatedSectionHeaderHeight父虑、 estimatedSectionFooterHeight 三個高度估算屬性由默認的0變成了UITableViewAutomaticDimension,導致高度計算不對授药。
解決方法:實現(xiàn)對應(yīng)方法或把預估的三個屬性值設(shè)為0士嚎。
目前項目中由此引起的問題不大。
問題三:UISearchBar高度適配
1悔叽、SearchBar在Navi的titleView中莱衩,高度發(fā)生變化
現(xiàn)象:
解決辦法:自定義View,重寫系統(tǒng)方法骄蝇,賦值給titleview膳殷。如下:
- (CGSize)intrinsicContentSize {
if (@available(iOS 11.0, *)) {
return UILayoutFittingCompressedSize;
}
return CGSizeZero;
}
iPhone X適配:
1、啟動圖和AppIcon
啟動圖規(guī)格尺寸:1125 * 2436 (357pt * 812pt @3x)
AppIcon尺寸:多了一個App Store的圖標九火。
2赚窃、劉海布局
大部分的系統(tǒng)控件,如NavigationBar岔激、TabBar勒极、表單等會自動適配iPhone X的屏幕,無需適配虑鼎,但是如果自定義的話辱匿,就得手動適配啦,NavigationBar空出劉海位置炫彩,TabBar空出HomeBar位置匾七,都位于安全區(qū)域以內(nèi)。
3江兢、橫屏布局昨忆,尚未研究。
Xcode 9的小Tips:
1杉允、導入圖片問題
直接將圖片拖入工程的粗暴方式已經(jīng)不行啦邑贴, 會導致無法讀取圖片,可以通過“Add File To ....”叔磷,不習慣好吧拢驾。Xcode 9可以打開Assets,將圖片資源直接拖進去改基,直觀方便繁疤。
2、Assets中添加顏色
在Asset中,可以創(chuàng)建顏色了嵌洼。右鍵選擇New image set案疲,填充RGBA值或十六進制值即可。使用中直接使用新的colorwithname麻养,參數(shù)填入創(chuàng)建時的名字即可。使用時一定記得區(qū)分系統(tǒng)版本诺舔。
3鳖昌、command鍵復原,直接跳轉(zhuǎn)
可在Preferences --> Navigation --> Command-click on Code 中選擇Jumps to Defintion即可低飒。