【轉(zhuǎn)】適配iOS11&iPhoneX的一些坑

作者:張?jiān)掳?br> 鏈接:http://www.lxweimin.com/p/c355cc4b12c2
來源:簡書
著作權(quán)歸作者所有。

前陣子項(xiàng)目開發(fā)忙成狗,就一直沒做iOS11的適配,直到XcodeGM版發(fā)布后,我胸有成竹的在iPhoneX上跑起項(xiàng)目,整個(gè)人都涼透了...下面總結(jié)一下我遇到的坑,不是很全面,日后補(bǔ)充。

導(dǎo)航欄

導(dǎo)航欄高度的變化

iOS11之前導(dǎo)航欄默認(rèn)高度為64pt(這里高度指statusBar + NavigationBar),iOS11之后如果設(shè)置了prefersLargeTitles = YES
則為96pt,默認(rèn)情況下還是64pt,但在iPhoneX上由于劉海的出現(xiàn)statusBar由以前的20pt變成了44pt,所以iPhoneX上高度變?yōu)?8pt,如果項(xiàng)目里隱藏了導(dǎo)航欄加了自定義按鈕之類的,這里需要注意適配一下。

導(dǎo)航欄圖層及對titleView布局的影響

iOS11之前導(dǎo)航欄的title是添加在UINavigationItemView
上面,而navigationBarButton則直接添加在UINavigationBar
上面,如果設(shè)置了titleView,則titleView也是直接添加在UINavigationBar
上面。iOS11之后,大概因?yàn)?code>largeTitle
的原因,視圖層級發(fā)生了變化,如果沒有給titleView賦值,則titleView會(huì)直接添加在_UINavigationBarContentView
上面,如果賦值了titleView,則會(huì)把titleView添加在_UITAMICAdaptorView
上,而navigationBarButton被加在了_UIButtonBarStackView
上,然后他們都被加在了_UINavigationBarContentView
上,如圖:

圖1
圖1

所以如果你的項(xiàng)目是自定義的navigationBar,那么在iOS11上運(yùn)行就可能出現(xiàn)布局錯(cuò)亂的bug,解決辦法是重寫UINavigationBar
layoutSubviews
方法,調(diào)整布局,上代碼:

- (void)layoutSubviews {
      [super layoutSubviews]; //注意導(dǎo)航欄及狀態(tài)欄高度適配 
      self.frame = CGRectMake(0, 0, CGRectGetWidth(self.frame), naviBarHeight); 
      for (UIView *view in self.subviews) { 
          if([NSStringFromClass([view class]) containsString:@"Background"]) {   
              view.frame = self.bounds; 
          } else if ([NSStringFromClass([view class]) containsString:@"ContentView"]) { 
              CGRect frame = view.frame; 
              frame.origin.y = statusBarHeight; 
              frame.size.height = self.bounds.size.height - frame.origin.y; 
              view.frame = frame; 
          } 
     }
}

再補(bǔ)充一點(diǎn),看了簡書App適配iOS11發(fā)現(xiàn)titleView支持autolayout
,這要求titleView必須是能夠自撐開的或?qū)崿F(xiàn)了- intrinsicContentSize
方法

- (CGSize)intrinsicContentSize {
       return UILayoutFittingExpandedSize;
}

UIScrollView、UITableView、UICollectionView
大家在iOS11設(shè)備上運(yùn)行出現(xiàn)最多問題應(yīng)該就是tableview
莫名奇妙的偏移20pt或者64pt了。。原因是iOS11棄用了automaticallyAdjustsScrollViewInsets
屬性,取而代之的是UIScrollView
新增了contentInsetAdjustmentBehavior
屬性,這一切的罪魁禍?zhǔn)锥际切乱氲膕afeArea
,關(guān)于safeArea
適配這篇文章iOS 11 安全區(qū)域適配總結(jié)講的很詳細(xì),感興趣的可以看下,我直接貼適配代碼,因?yàn)榈桶姹局苯佑?code>contentInsetAdjustmentBehavior
會(huì)報(bào)警告,所有定義了如下的宏(感謝@炒雞范的指正,之前的宏犯了個(gè)低級錯(cuò)誤...現(xiàn)改為)

#define adjustsScrollViewInsets(scrollView)\
do {\
_Pragma("clang diagnostic push")\
_Pragma("clang diagnostic ignored \"-Warc-performSelector-leaks\"")\
if ([scrollView respondsToSelector:NSSelectorFromString(@"setContentInsetAdjustmentBehavior:")]) {\ 
NSMethodSignature *signature = [UIScrollView instanceMethodSignatureForSelector:@selector(setContentInsetAdjustmentBehavior:)];\
 NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];\ 
NSInteger argument = 2;\
invocation.target = scrollView;\ 
invocation.selector = @selector(setContentInsetAdjustmentBehavior:);\ 
[invocation setArgument:&argument atIndex:2];\ 
[invocation retainArguments];\ 
[invocation invoke];\
}\
_Pragma("clang diagnostic pop")\
} while (0)

還有的發(fā)現(xiàn)某些界面tableView
sectionHeader、sectionFooter
高度與設(shè)置不符的問題,在iOS11中如果不實(shí)現(xiàn)
-tableView: viewForHeaderInSection:-tableView: viewForFooterInSection:,
-tableView: heightForHeaderInSection:- tableView: heightForFooterInSection:
不會(huì)被調(diào)用,導(dǎo)致它們都變成了默認(rèn)高度,這是因?yàn)閠ableView
在iOS11默認(rèn)使用Self-Sizing
,tableView
estimatedRowHeight 、estimatedSectionHeaderHeight 、estimatedSectionFooterHeight
三個(gè)高度估算屬性由默認(rèn)的0變成了UITableViewAutomaticDimension
,解決辦法簡單粗暴,就是實(shí)現(xiàn)對應(yīng)方法或把這三個(gè)屬性設(shè)為0。
如果你使用了Masonry
,那么你需要適配safeArea

if (@available(iOS 11.0, *)) { 
    make.edges.equalTo()(self.view.safeAreaInsets)
} else { 
    make.edges.equalTo()(self.view)
}

iPhoneX

LaunchImage

關(guān)于iPhoneX(我就不吐槽劉海了...),如果你的APP在iPhoneX上運(yùn)行發(fā)現(xiàn)沒有充滿屏幕,上下有黑色區(qū)域,那么你應(yīng)該也像我一樣LaunchImage
沒有用storyboard,而是用的Assets,解決辦法如圖,啟動(dòng)圖的尺寸為1125x2436
,or you can iOS開發(fā)時(shí)如何使用 Launch Screen Storyboard。

圖2
圖2

TabBarController

因?yàn)槲覀兊捻?xiàng)目用了第三方的TabBarController
,在iPhoneX運(yùn)行,tabBar看起來怪怪的...估計(jì)作者要等到猴年馬月才適配iPhoneX,項(xiàng)目又著急上線,就自己修改了第三方,主要是tabBar
高度及tabBarItem
偏移適配,iPhoneX由于底部安全區(qū)的原因UITabBar高度由 49pt變成了83pt,
可以通過判斷機(jī)型來修改相關(guān)界面代碼

#define kDevice_Is_iPhoneX ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size) : NO)

目前遇到的就這些坑,歡迎大家指正補(bǔ)充~
作為一名iOS開發(fā)人員,想到當(dāng)年嘲笑Android開發(fā)蛋疼的適配各種機(jī)型心情如圖...


image

image

最后奉上WWDC官方視頻:
Updating Your App for iOS 11
Building Apps for iPhone X
Designing for iPhone X

作者:張?jiān)掳腈溄樱?a href="http://www.lxweimin.com/p/c355cc4b12c2" target="_blank">http://www.lxweimin.com/p/c355cc4b12c2來源:簡書著作權(quán)歸作者所有。感謝作者的及時(shí)分享

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 博客傳送門前陣子項(xiàng)目開發(fā)忙成狗,就一直沒做iOS11的適配,直到XcodeGM版發(fā)布后,我胸有成竹的在iPhone...
    張?jiān)掳?/span>閱讀 30,080評論 55 239
  • 導(dǎo)航欄 導(dǎo)航欄高度的變化 iOS11之前導(dǎo)航欄默認(rèn)高度為64pt(這里高度指statusBar + Navigat...
    西門淋雨閱讀 767評論 0 0
  • 導(dǎo)航欄導(dǎo)航欄高度的變化iOS11之前導(dǎo)航欄默認(rèn)高度為64pt(這里高度指statusBar + Navigatio...
    貝勒老爺閱讀 659評論 0 5
  • 前陣子項(xiàng)目開發(fā)忙成狗,就一直沒做iOS11的適配,直到XcodeGM版發(fā)布后,我胸有成竹的在iPhoneX上跑起項(xiàng)...
    Gaizka閱讀 837評論 0 0
  • 離家已經(jīng)整整十三年了。 有時(shí)想起家,記憶竟還都停留在小時(shí)候。 一個(gè)大雪封門的日子,雪停后,我和父親一起在院子里掃雪...
    心樂集閱讀 558評論 0 4