前言
最近公司的很多流量產(chǎn)品需要適配iOS 11 和iPhone X鸭津,由于公司的iPhone X到的比較晚扯罐,拖了好久才對(duì)這些流量產(chǎn)品進(jìn)行更新滋捶。
問題
- 首先一個(gè)很明顯的適配問題市咽,就是打開app的時(shí)候沒有全屏偷仿,這時(shí)候要加入一張對(duì)應(yīng)尺寸的啟動(dòng)圖片就可以鸵赫。
- 豎屏尺寸:1125px × 2436px(375pt × 812pt @3x)
- 橫屏尺寸:2436px × 1125px(812pt × 375pt @3x)
- 跟啟動(dòng)屏有關(guān)的當(dāng)然還有一個(gè)問題衣屏,那就是獲取屏幕的大小:[[UIScreen mainScreen] bounds].size 加入上面的圖片就可以了
導(dǎo)航欄
-
navigationItem.titleView
= 自定義view
, 這時(shí)候這個(gè)自定義的view
的大小就會(huì)出現(xiàn)問題奉瘤,而且有點(diǎn)擊時(shí)間也不會(huì)觸發(fā)勾拉。首先煮甥,在自定義titleview
里重寫intrinsicContentSize
屬性,代碼如下@property(nonatomic, assign) CGSize intrinsicContentSize;
然后在 self.navigationItem.titleView = _titleView; 之前加入下面的代碼:
_titleView.intrinsicContentSize = CGSizeMake(200, 40);
自定義的view
還是要設(shè)置frame
藕赞,不然不是iOS11還是可能出問題成肘。
- 導(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批销,由于劉海多出了24pt的高度洒闸,如果項(xiàng)目里隱藏了導(dǎo)航欄加了自定義按鈕之類的,這里需要注意適配一下均芽。
在viewSafeAreaInsetsDidChange
方法里面打印NSLog(@"%@",NSStringFromUIEdgeInsets(self.view.safeAreaInsets))
;即可知道安全區(qū)域的邊界
-
在iOS7之后,我們?cè)谠O(shè)置
UINavigationItem
的leftBarButtonItem
,rightBarButtonItem
的時(shí)候都會(huì)造成位置的偏移,我們經(jīng)常習(xí)慣使用下面這個(gè)方法來調(diào)整下間距+(UIBarButtonItem *)fixedSpaceWithWidth:(CGFloat)width {` UIBarButtonItem *fixedSpace = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; fixedSpace.width = width; return fixedSpace; }
但是在iOS11沒有效果了丘逸,可以通過過改變按鈕的 contentEdgeInsets
和imageEdgeInsets
的值成功改變了按鈕的偏移問題,單獨(dú)設(shè)置contentEdgeInsets
也可達(dá)到一定的效果
底部tarbar
- iPhone x:
Tabbar
從49pt變?yōu)?3pt掀宋,如果是自己定義的tabbar
需要自己加上34的高度深纲,否則會(huì)點(diǎn)不到對(duì)應(yīng)tabbar
。如果是隱藏的tabbar
的話劲妙,比如底部放了一個(gè)banner
廣告的話湃鹊,這時(shí)候也需要調(diào)整對(duì)應(yīng)的高度,在xcode中調(diào)整了下如果隱藏tabbar
镣奋,還要在底部放廣告的話可以距離底部24pt币呵,蘋果tabbar
多加了34,比點(diǎn)擊距離多加了10pt侨颈,應(yīng)該是讓用戶體驗(yàn)更加的好點(diǎn)余赢,不然24的話感覺快點(diǎn)到底部觸摸欄的樣子。
UITableView and UICollectionView
-
在iOS 11上運(yùn)行tableView向下偏移64px或者20px哈垢,因?yàn)閕OS 11廢棄了
automaticallyAdjustsScrollViewInsets
没佑,而是給UIScrollView增加了contentInsetAdjustmentBehavior
屬性。避免這個(gè)坑的方法是要判斷if (@available(iOS 11.0, *)) { _tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; }else { self.automaticallyAdjustsScrollViewInsets = NO; }
-
IOS11以后温赔,
Self-Sizing
默認(rèn)開啟,包括Headers
,footers
鬼癣。如果項(xiàng)目中沒使用estimatedRowHeight
屬性陶贼,在IOS11下會(huì)有奇奇怪怪的現(xiàn)象,默認(rèn)如果不去實(shí)現(xiàn)viewForHeaderInSection
就不會(huì)調(diào)用heightForHeaderInSection
,尾部試圖一樣待秃,因?yàn)镮OS11之前拜秧,estimatedRowHeight
默認(rèn)為0,Self-Sizing
自動(dòng)打開后章郁,contentSize
和contentOffset
都可能發(fā)生改變枉氮≈狙埽可以通過以下方式禁用:self.tableView.estimatedRowHeight = 0; self.tableView.estimatedSectionHeaderHeight = 0; self.tableView.estimatedSectionFooterHeight = 0;
-
列表/頁面偏移,設(shè)置工程中的UITableView聊替、UICollectionView楼肪、UIScrollView的
contentInsetAdjustmentBehavior
屬性,如下:if (@available(iOS 11.0, *)){ _tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; }
總的來說所有繼承與Scrollview 及其子類都需要設(shè)置 contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever
惹悄,每個(gè)設(shè)置很麻煩春叫,沒關(guān)系。由于UIView及其子類都遵循UIAppearance
協(xié)議泣港,我們可以進(jìn)行全局配置:
// AppDelegate 進(jìn)行全局設(shè)置
if (@available(iOS 11.0, *)){
[[UIScrollView appearance] setContentInsetAdjustmentBehavior:UIScrollViewContentInsetAdjustmentNever];
}
-
當(dāng)你在tableView 里面嵌套collectionView 的時(shí)候有可能出現(xiàn)一下錯(cuò)誤:
Assertion failure in -[UICollectionViewData validateLayoutInRect:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3694.4.18/UICollectionViewData.m:435 2017-11-15 15:59:08.616969+0800 tbEmojiGuangchang[70423:3415148] invalid mode 'kCFRunLoopCommonModes' provided to CFRunLoopRunSpecific - break on _CFRunLoopError_RunCalledWithInvalidMode to debug. This message will only appear once per execution.
libc++abi.dylib: terminate_handler unexpectedly threw an exception
只要在刷新collectionView之前調(diào)用[collectionView.collectionViewLayout invalidateLayout]
就行暂殖。
-(NSInteger) numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
[collectionView.collectionViewLayout invalidateLayout];
return 1;
}
-
相冊(cè)權(quán)限
iOS11之后:默認(rèn)開啟訪問相冊(cè)權(quán)限(讀權(quán)限),無需用戶授權(quán)当纱,無需添加NSPhotoLibraryUsageDescription
呛每,適配iOS11之前的還是需要加的。 添加圖片到相冊(cè)(寫權(quán)限)坡氯,需要用戶授權(quán)晨横,需要添加NSPhotoLibraryAddUsageDescription
,相冊(cè)的權(quán)限狀態(tài)有以下四種狀態(tài):PHAuthorizationStatusNotDetermined = 0, // User has not yet made a choice with regards to this application PHAuthorizationStatusRestricted, // This application is not authorized to access photo data. // The user cannot change this application’s status, possibly due to active restrictions // such as parental controls being in place. PHAuthorizationStatusDenied, // User has explicitly denied this application access to photos data. PHAuthorizationStatusAuthorized // User has authorized this application to access photos data.
iOS11之前如果還沒請(qǐng)求訪問相冊(cè)權(quán)限的話狀態(tài)是:PHAuthorizationStatusNotDetermined
,用戶如果點(diǎn)擊不允許訪問相冊(cè)的話狀態(tài)是:PHAuthorizationStatusDenied
,但是在iOS11就很奇葩,還沒請(qǐng)求訪問相冊(cè)權(quán)限和用戶如果點(diǎn)擊不允許訪問相冊(cè)的狀態(tài)都是PHAuthorizationStatusNotDetermined
廉沮,導(dǎo)致不能判斷是否是用戶點(diǎn)擊不允許的操作颓遏,也就沒辦法彈出那個(gè)引導(dǎo)用戶去設(shè)置開啟相冊(cè)權(quán)限的窗口。我這邊的做法是如果應(yīng)用是有需要添加相片到相冊(cè)的滞时,要提前請(qǐng)求相冊(cè)功能:
oc 代碼:
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
}];
swift 代碼:
if #available(iOS 11.0, *) {
let library: PHAuthorizationStatus = PHPhotoLibrary.authorizationStatus()
if(library == PHAuthorizationStatus.notDetermined){
PHPhotoLibrary.requestAuthorization { (status) in
}
}
}
- 位置權(quán)限
在IOS11叁幢,原有的NSLocationAlwaysUsageDeion
被降級(jí)為NSLocationWhenInUseUsageDeion
。因此坪稽,在原來項(xiàng)目中使用requestAlwaysAuthorization
獲取定位權(quán)限曼玩,而未在plist文件中配置NSLocationAlwaysAndWhenInUseUsageDeion
,系統(tǒng)框不會(huì)彈出窒百。建議新舊key值都在plist里配置黍判,反正我試下來是沒有問題,唯一的區(qū)別是使用requestAlwaysAuthorization
獲取權(quán)限 IOS11系統(tǒng)彈框會(huì)把幾種權(quán)限級(jí)別全部列出篙梢,供用戶選擇顷帖,顯然更人性化了〔持停快去更新你的info.plist
<!-- 位置 -->
<key>NSLocationUsageDescription</key>
<string>獲取地理位置贬墩,精準(zhǔn)推送服務(wù)</string>
<!-- 在使用期間訪問位置 -->
<key>NSLocationWhenInUseUsageDescription</key>
<string>獲取地理位置,精準(zhǔn)推送服務(wù)</string>
<!-- 始終訪問位置 -->
<key>NSLocationAlwaysUsageDescription</key>
<string>App需要您的同意,才能始終訪問位置</string>
<!-- iOS 11訪問位置 -->
<key>NSLocationAlwaysAndWhenInUseUsageDeion</key>
<string>App需要您的同意,才能始終訪問位置</string>
-
使用第三方網(wǎng)絡(luò)監(jiān)測(cè)庫報(bào)錯(cuò)
325120-0850ff880b326807.png
解決方式如下:替換成如下代碼:
__Check_Compile_Time(sizeof(ICMPHeader) == 8);
__Check_Compile_Time(offsetof(ICMPHeader, type) == 0);
__Check_Compile_Time(offsetof(ICMPHeader, code) == 1);
__Check_Compile_Time(offsetof(ICMPHeader, checksum) == 2);
__Check_Compile_Time(offsetof(ICMPHeader, identifier) == 4);
__Check_Compile_Time(offsetof(ICMPHeader, sequenceNumber) == 6)
后續(xù)更新...
-
跳轉(zhuǎn)appStore評(píng)論的鏈接更換了妄呕,很正常陶舞,因?yàn)閕OS11之后appStore就大改版了,當(dāng)然跳到里面的鏈接應(yīng)該也是會(huì)有所變化的绪励,之前iOS11的鏈接是這樣的:
http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?id=XXXXXXXX&pageNumber=0&sortOrdering=2&type=Purple+Software&mt=8"
iOS11之后需要改稱以下這樣肿孵,當(dāng)然iOS11之前這個(gè)鏈接也是適用的:
itms-apps://itunes.apple.com/cn/app/idXXXXXX?mt=8&action=write-review
-
UIToolBar 的坑唠粥,當(dāng)你使用view集成UIToolBar的時(shí)候停做,這個(gè)時(shí)候使用xcode9運(yùn)行的時(shí)候會(huì)發(fā)現(xiàn)一個(gè)非澄罾ⅲ坑的問題,就是在view的最頂層會(huì)多出一層UIToolBarContenVIew出來雅宾,到時(shí)你的整個(gè)view沒辦法點(diǎn)擊养涮,建議不要用UIToolbar來繼承。
CA99B4BE-B322-453E-951E-A0B5B32E4530.png
總結(jié)
以上是我在適配我的一些產(chǎn)品的時(shí)候碰到的一些問題眉抬,當(dāng)然還有一些其他很小的細(xì)節(jié)有問題贯吓,只需要稍微調(diào)整就行,在這里就不提了蜀变,蘋果每次更新一個(gè)大版本的時(shí)候都會(huì)出現(xiàn)各種各樣的問題悄谐,很多東西也變得越來越復(fù)雜,后面有在項(xiàng)目中碰到問題會(huì)在繼續(xù)更新~