1-2. iOS11/iPhoneX最新適配指南

iPhone發(fā)布會(huì)前,就隱隱感覺(jué)到一波適配工作要襲來(lái)的趕腳,果然不出所料。
新版iPhone的適配工作主要集中在iPhoneX上,相信大家已經(jīng)對(duì)iPhoneX的劉海記憶深刻了,除了吐槽,留給我們的還有比較麻煩的適配工作。下面簡(jiǎn)單分享下在整理過(guò)程中發(fā)現(xiàn)的適配注意點(diǎn)。(適配工作主要在UI方面,后續(xù)發(fā)現(xiàn)的適配點(diǎn)會(huì)陸續(xù)補(bǔ)充到該文檔中)

上下黑邊問(wèn)題

運(yùn)行新版Xcode的iPhoneX模擬器,你可能發(fā)現(xiàn)之前的APP在iPhoneX屏幕沒(méi)填充滿,上下有黑色區(qū)域,應(yīng)該是你的app之前未用LaunchScreen.Storyboard作為啟動(dòng)頁(yè)面,可以使用LaunchScreen來(lái)當(dāng)做入場(chǎng)頁(yè)面,這樣APP才會(huì)自動(dòng)適配為iPhoneX的大小?;蛘咝薷腁ssets中的LaunchImage,添加iPhoneX的Launch圖如下(1125*2436)。

iOS11新增版本判斷API

iOS11版本現(xiàn)在有了簡(jiǎn)單的API,OC也開(kāi)始支持swfit的@available語(yǔ)法,不用再手寫iOS版本判斷了。

if (@available(iOS 11.0, *)) {
    //版本適配
}
//或者
#ifdef __IPHONE_11_0
#endif

目前沒(méi)發(fā)現(xiàn)有iPhoneX的機(jī)型判斷API,暫時(shí)可以使用size來(lái)做代替判斷。

//判斷是否iPhone X
#define IS_iPhoneX ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size) : NO)
//或者
#define kDevice_iPhoneX CGSizeEqualToSize(CGSizeMake(375, 812), [[UIScreen mainScreen] bounds].size)
//或者
 if ([UIScreen mainScreen].bounds.size.height == 812) {
        NSLog(@"this is iPhone X");
    }

UI適配

導(dǎo)航欄適配

iPhoneX由于多了大圓角、傳感器(齊劉海)以及底部訪問(wèn)主屏幕的指示遮擋,所以需要注意原有這部分內(nèi)容的設(shè)計(jì)。
iOS11前導(dǎo)航欄的高度是64,其中statusBar的高度為20,而iPhoneX的statusBar高度變?yōu)榱?4,如果是自定義的NaviBar,這部分需要做相應(yīng)的適配。

iPhoneX的底部增加了虛擬Home區(qū),由于安全區(qū)域的原因默認(rèn)tabBar的高度由49變?yōu)?3,增高了34,所以自定義的底部TabBar也需要需改其適配方案。
可能有部分APP使用了RN來(lái)實(shí)現(xiàn)頁(yè)面,不要忘了在RN中修改相應(yīng)NaviBar/TabBar的高度。

[圖片上傳中...(image-b5608-1526548047385-1)]

安全區(qū)域

安全區(qū)域定義了view中可視區(qū)域的部分,幫助我們將view放置在整個(gè)屏幕的可視的部分。即使把navigationbar設(shè)置為透明的,系統(tǒng)也認(rèn)為安全區(qū)域是從navigationbar的bottom開(kāi)始的。這樣保證不被系統(tǒng)的狀態(tài)欄、或父視圖提供的view如導(dǎo)航欄覆蓋。

[圖片上傳中...(image-7c2da3-1526548047385-0)]

iOS11的UIViewController和UIView新加了-(void)viewSafeAreaInsetsDidChange方法,當(dāng)安全區(qū)域改變后該方法會(huì)被調(diào)用。然后在該方法中根據(jù)safeAreaInses屬性更新子視圖中控件的布局位置。
當(dāng)然如果你要改變一個(gè)UIViewController的safeAreaInsets值, 可以通過(guò)設(shè)置addtionalSafeAreaInsets屬性來(lái)實(shí)現(xiàn), 例如你要自定義一些特殊的樣式時(shí)。
需要注意的是viewSafeAreaInsetsDidChange在UIViewController中第一次調(diào)用的時(shí)間是在-(void)viewWillAppear:(BOOL)animated調(diào)用之后, 在- (void)viewWillLayoutSubviews調(diào)用之前。所以可以在viewWillAppear里設(shè)置受影響的頁(yè)面的addtionalSafeAreaInsets屬性。

- (void)viewSafeAreaInsetsDidChange{
    [super viewSafeAreaInsetsDidChange];
    if (@available(iOS 11.0, *)) {
        NSLog(@"safeAreaInset list= %@",NSStringFromUIEdgeInsets(self.view.safeAreaInsets));
        NSLog(@"safeAreaLayout list= %@",self.view.safeAreaLayoutGuide);
    }
}

UIScrollView & UITableView

測(cè)試過(guò)程中發(fā)現(xiàn)tableView會(huì)有20pt/64pt的偏移,其原因是由于iOS 11廢棄了UIViewController的automaticallyAdjustsScrollViewInsets屬性,新增了contentInsetAdjustmentBehavior屬性,所以當(dāng)超出安全區(qū)域時(shí)系統(tǒng)自動(dòng)調(diào)整了SafeAreaInsets,進(jìn)而影響了adjustedContentInset,在iOS11中決定tableView內(nèi)容與邊緣距離的是adjustedContentInset,所以需要設(shè)置UIScrollView的contentInsetAdjustmentBehavior屬性。

1.手動(dòng)適配
如果你使用了UITableView、UIScrollView,可以直接使用以下代碼做適配,這樣系統(tǒng)就不會(huì)主動(dòng)為你設(shè)置邊緣距離,但是你可能需要手動(dòng)適配UITableView的contenteInset。

#ifdef __IPHONE_11_0  
// 單獨(dú)作用與某個(gè)tableView
if ([tableView respondsToSelector:@selector(setContentInsetAdjustmentBehavior:)]) {
  tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
// 作用與所有的UIScrollView
UIScrollView.appearance.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
// 設(shè)置view的寬高
tableView.contentInset = UIEdgeInsetsMake(0, 0, 34, 0);
#endif

2.自動(dòng)適配
設(shè)置contentInsetAdjustmentBehavior屬性為UIScrollViewContentInsetAdjustmentAutomatic,則系統(tǒng)會(huì)自動(dòng)計(jì)算contentView的偏移量。

3.設(shè)置安全區(qū)域的addtionalSafeAreaInset
某些情況下,你需要頂部區(qū)域,比如廣告區(qū)域覆蓋Status,則可以設(shè)置相應(yīng)頁(yè)面的addtionalSafeAreaInset屬性,這樣系統(tǒng)不會(huì)將safeArea上調(diào)到從status開(kāi)始。這樣可以提供更好的用戶體驗(yàn)。
例如如果你的SafeAreaInset值為(44,0,0,0),則需要設(shè)置相應(yīng)的additionalSafeAreaInsets值為(-44,0,0,0)。

if (@available(iOS 11.0, *)) {
    self.additionalSafeAreaInsets = UIEdgeInsetsMake(-44, 0, 0, 0);
} else {
    // Fallback on earlier versions
}

4.iOS11開(kāi)始UITableView開(kāi)啟了自動(dòng)估算行高,estimatedRowHeight estimatedSectionHeaderHeight estimatedSectionFooterHeight三個(gè)高度估算屬性由默認(rèn)的0變成了UITableViewAutomaticDimension,所以heightForHeaderInSection和viewForHeaderInSection應(yīng)該一起使用,不然tableView頂部滑動(dòng)的時(shí)候會(huì)有空白。
在適配過(guò)程中發(fā)現(xiàn)UITableView會(huì)在Header/Footer返回size為負(fù)值的情況下會(huì)(之前遺漏的bug)崩潰,這塊可以自查下,而iOS11之前的版本不會(huì)。

其他方案……

借鑒某人實(shí)踐中遇到的坑

另外有人對(duì)iPhoneX整個(gè)UIWindow做了內(nèi)容的調(diào)整,只是UI還是有點(diǎn)丑,感興趣的同學(xué)可以去看看該GitHub,不過(guò)可能這樣的設(shè)計(jì)方案不會(huì)通過(guò)APPLE的審核。

API適配

LocalAuthentication 本地認(rèn)證

本地認(rèn)證框架提供了從具有指定安全策略(密碼或生物學(xué)特征)的用戶請(qǐng)求身份驗(yàn)證的功能。例如,要求用戶僅使用Face ID或Touch ID進(jìn)行身份驗(yàn)證,可使用以下代碼:

let myContext = LAContext()   
let myLocalizedReasonString = <#String explaining why app needs authentication#>    
var authError: NSError?   
if #available(iOS 8.0, macOS 10.12.1, *) {   
    if myContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &authError) {   
        myContext.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: myLocalizedReasonString) { success, evaluateError in
            if success {  
                // 用戶驗(yàn)證通過(guò)  
            } else {  
                // 用戶驗(yàn)證失敗,處理失敗信息  
            }  
        }  
    } else {  
        // 不能執(zhí)行策略驗(yàn)證,處理驗(yàn)證錯(cuò)誤信息  
    }  
} else {  
    // Fallback on earlier versions
}

LAContext新增API如下:

  1. biometryType屬性返回當(dāng)前設(shè)備支持的生物學(xué)特征驗(yàn)證方式,他的值可以分別為typeFaceID、typeTouchID或者none。
  2. localizedReason需要驗(yàn)證時(shí)展示在彈框上的提示信息
參考文檔
  1. https://developer.apple.com/videos/fall2017/
  2. https://developer.apple.com/iphone/
  3. https://developer.apple.com/ios/human-interface-guidelines/overview/iphone-x/
Tips

iPhone X 側(cè)邊按鈕的使用方式:

  • 按一下鎖屏;
  • 按兩下 Apple Pay;
  • 按三下輔助功能快捷鍵(比如 VoiceOver);
  • 按五下 SOS;
  • 短按 Siri;
  • 長(zhǎng)按關(guān)機(jī);
  • 按一下+Volume Up 截屏。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 原文鏈接: http://fighting300.com... iPhone發(fā)布會(huì)前,就隱隱感覺(jué)到一波適配工作要襲...
    fighting300閱讀 3,677評(píng)論 0 18
  • 前言 蘋果WWDC開(kāi)發(fā)者大會(huì)上,終于發(fā)布了大家期待已久的iOS 11,有些新特性功能確實(shí)出人意料。不過(guò)大的方面蘋果...
    Mr_Say_Yes閱讀 3,467評(píng)論 6 15
  • 一、前言 iOS11發(fā)布也有一段時(shí)間了,每次版本升級(jí),相關(guān)的適配工作當(dāng)然是下個(gè)版本的核心工作之一。而且這次iOS1...
    半緣魔君閱讀 1,887評(píng)論 1 3
  • 一、前言 iOS11發(fā)布也有一段時(shí)間了,每次版本升級(jí),相關(guān)的適配工作當(dāng)然是下個(gè)版本的核心工作之一。而且這次iOS1...
    景銘巴巴閱讀 11,146評(píng)論 8 105
  • 譯文地址:Java中常見(jiàn)的坑 概述 Java是門極簡(jiǎn)風(fēng)格的語(yǔ)言,比其它語(yǔ)言相比,它故意保持較少的特性,不僅在有些不...
    IT程序獅閱讀 1,021評(píng)論 0 3

友情鏈接更多精彩內(nèi)容