iOS11, Xcode9 and iphone X適配
前言
最近公司的很多流量產品需要適配iOS 11 和iPhone X,由於公司的iPhone X到的比較晚,拖了好久才對這些流量產品進行更新。
問題
- 首先一個很明顯的適配問題,就是開啟app的時候沒有全屏,這時候要加入一張對應尺寸的啟動圖片就可以。
- 豎屏尺寸:1125px × 2436px(375pt × 812pt @3x)
- 橫屏尺寸:2436px × 1125px(812pt × 375pt @3x)
- 跟啟動屏有關的當然還有一個問題,那就是獲取螢幕的大小:[[UIScreen mainScreen] bounds].size 加入上面的圖片就可以了
導航欄
-
navigationItem.titleView
= 自定義view
, 這時候這個自定義的view
的大小就會出現問題,而且有點選時間也不會觸發。首先,在自定義titleview
裡重寫intrinsicContentSize
屬性,程式碼如下@property(nonatomic, assign) CGSize intrinsicContentSize;
然後在 self.navigationItem.titleView = _titleView; 之前加入下面的程式碼:
_titleView.intrinsicContentSize = CGSizeMake(200, 40);
自定義的view
還是要設定frame
,不然不是iOS11還是可能出問題。
- 導航欄高度的變化
iOS11之前導航欄預設高度為64pt(這裡高度指statusBar + NavigationBar),iOS11之後如果設定了prefersLargeTitles = YES
則為96pt,預設情況下還是64pt,但在iPhoneX上由於劉海的出現statusBar由以前的20pt變成了44pt,所以iPhoneX上高度變為88pt,由於劉海多出了24pt的高度,如果專案裡隱藏了導航欄加了自定義按鈕之類的,這裡需要注意適配一下。
在viewSafeAreaInsetsDidChange
方法裡面列印NSLog(@"%@",NSStringFromUIEdgeInsets(self.view.safeAreaInsets))
;即可知道安全區域的邊界
-
在iOS7之後,我們在設定
UINavigationItem
的leftBarButtonItem
,rightBarButtonItem
的時候都會造成位置的偏移,我們經常習慣使用下面這個方法來調整下間距+(UIBarButtonItem *)fixedSpaceWithWidth:(CGFloat)width {` UIBarButtonItem *fixedSpace = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; fixedSpace.width = width; return fixedSpace; }
但是在iOS11沒有效果了,可以通過過改變按鈕的 contentEdgeInsets
和imageEdgeInsets
的值成功改變了按鈕的偏移問題,單獨設定contentEdgeInsets
也可達到一定的效果
底部tarbar
- iPhone x:
Tabbar
從49pt變為83pt,如果是自己定義的tabbar
需要自己加上34的高度,否則會點不到對應tabbar
。如果是隱藏的tabbar
的話,比如底部放了一個banner
廣告的話,這時候也需要調整對應的高度,在xcode中調整了下如果隱藏tabbar
,還要在底部放廣告的話可以距離底部24pt,蘋果tabbar
多加了34,比點選距離多加了10pt,應該是讓使用者體驗更加的好點,不然24的話感覺快點到底部觸控欄的樣子。
UITableView and UICollectionView
-
在iOS 11上執行tableView向下偏移64px或者20px,因為iOS 11廢棄了
automaticallyAdjustsScrollViewInsets
,而是給UIScrollView增加了contentInsetAdjustmentBehavior
屬性。避免這個坑的方法是要判斷if (@available(iOS 11.0, *)) { _tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; }else { self.automaticallyAdjustsScrollViewInsets = NO; }
-
IOS11以後,
Self-Sizing
預設開啟,包括Headers
,footers
。如果專案中沒使用estimatedRowHeight
屬性,在IOS11下會有奇奇怪怪的現象,預設如果不去實現viewForHeaderInSection
就不會呼叫heightForHeaderInSection
,尾部試圖一樣,因為IOS11之前,estimatedRowHeight
預設為0,Self-Sizing
自動開啟後,contentSize
和contentOffset
都可能發生改變。可以通過以下方式禁用:self.tableView.estimatedRowHeight = 0; self.tableView.estimatedSectionHeaderHeight = 0; self.tableView.estimatedSectionFooterHeight = 0;
-
列表/頁面偏移,設定工程中的UITableView、UICollectionView、UIScrollView的
contentInsetAdjustmentBehavior
屬性,如下:if (@available(iOS 11.0, *)){ _tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; }
總的來說所有繼承與Scrollview 及其子類都需要設定 contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever
,每個設定很麻煩,沒關係。由於UIView及其子類都遵循UIAppearance
協議,我們可以進行全域性配置:
// AppDelegate 進行全域性設定
if (@available(iOS 11.0, *)){
[[UIScrollView appearance] setContentInsetAdjustmentBehavior:UIScrollViewContentInsetAdjustmentNever];
}
-
當你在tableView 裡面巢狀collectionView 的時候有可能出現一下錯誤:
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之前呼叫[collectionView.collectionViewLayout invalidateLayout]
就行。
-(NSInteger) numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
[collectionView.collectionViewLayout invalidateLayout];
return 1;
}
-
相簿許可權
iOS11之後:預設開啟訪問相簿許可權(讀許可權),無需使用者授權,無需新增NSPhotoLibraryUsageDescription
,適配iOS11之前的還是需要加的。 新增圖片到相簿(寫許可權),需要使用者授權,需要新增NSPhotoLibraryAddUsageDescription
,相簿的許可權狀態有以下四種狀態: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之前如果還沒請求訪問相簿許可權的話狀態是:PHAuthorizationStatusNotDetermined
,使用者如果點選不允許訪問相簿的話狀態是:PHAuthorizationStatusDenied
,但是在iOS11就很奇葩,還沒請求訪問相簿許可權和使用者如果點選不允許訪問相簿的狀態都是PHAuthorizationStatusNotDetermined
,導致不能判斷是否是使用者點選不允許的操作,也就沒辦法彈出那個引導使用者去設定開啟相簿許可權的視窗。我這邊的做法是如果應用是有需要新增相片到相簿的,要提前請求相簿功能:
oc 程式碼:
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
}];
swift 程式碼:
if #available(iOS 11.0, *) {
let library: PHAuthorizationStatus = PHPhotoLibrary.authorizationStatus()
if(library == PHAuthorizationStatus.notDetermined){
PHPhotoLibrary.requestAuthorization { (status) in
}
}
}
- 位置許可權
在IOS11,原有的NSLocationAlwaysUsageDeion
被降級為NSLocationWhenInUseUsageDeion
。因此,在原來專案中使用requestAlwaysAuthorization
獲取定位許可權,而未在plist檔案中配置NSLocationAlwaysAndWhenInUseUsageDeion
,系統框不會彈出。建議新舊key值都在plist裡配置,反正我試下來是沒有問題,唯一的區別是使用requestAlwaysAuthorization
獲取許可權 IOS11系統彈框會把幾種許可權級別全部列出,供使用者選擇,顯然更人性化了。快去更新你的info.plist
<!-- 位置 -->
<key>NSLocationUsageDescription</key>
<string>獲取地理位置,精準推送服務</string>
<!-- 在使用期間訪問位置 -->
<key>NSLocationWhenInUseUsageDescription</key>
<string>獲取地理位置,精準推送服務</string>
<!-- 始終訪問位置 -->
<key>NSLocationAlwaysUsageDescription</key>
<string>App需要您的同意,才能始終訪問位置</string>
<!-- iOS 11訪問位置 -->
<key>NSLocationAlwaysAndWhenInUseUsageDeion</key>
<string>App需要您的同意,才能始終訪問位置</string>
-
使用第三方網路監測庫報錯
解決方式如下:替換成如下程式碼:
__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)
後續更新...
-
跳轉appStore評論的連結更換了,很正常,因為iOS11之後appStore就大改版了,當然跳到裡面的連結應該也是會有所變化的,之前iOS11的連結是這樣的:
http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?id=XXXXXXXX&pageNumber=0&sortOrdering=2&type=Purple+Software&mt=8"
iOS11之後需要改稱以下這樣,當然iOS11之前這個連結也是適用的:
itms-apps://itunes.apple.com/cn/app/idXXXXXX?mt=8&action=write-review
-
UIToolBar 的坑,當你使用view整合UIToolBar的時候,這個時候使用xcode9執行的時候會發現一個非常坑的問題,就是在view的最頂層會多出一層UIToolBarContenVIew出來,到時你的整個view沒辦法點選,建議不要用UIToolbar來繼承。
總結
以上是我在適配我的一些產品的時候碰到的一些問題,當然還有一些其他很小的細節有問題,只需要稍微調整就行,在這裡就不提了,蘋果每次更新一個大版本的時候都會出現各種各樣的問題,很多東西也變得越來越複雜,後面有在專案中碰到問題會在繼續更新~
相關文章
- 開發日常 適配iOS11和iPhone XiOSiPhone
- 適配iPhoneX & iOS11iPhoneiOS
- 適配iphone XiPhone
- iOS11 適配iOS
- 前端iPhone X適配總結前端iPhone
- iPhone X + iOS 11 適配指南iPhoneiOS
- iOS MJRefresh適配ios11以及iPhoneXiOSiPhone
- cocos creator中適配iPhone XiPhone
- iOS11適配詳解iOS
- 微信小程式適配 iPhone X 總結微信小程式iPhone
- 10分鐘適配 iOS 11 & iPhone XiOSiPhone
- Unity適配iPhone X---關於Home鍵指示器適配UnityiPhone
- web app 一分鐘適配 iPhone XWebAPPiPhone
- iPhone X和iOS 11的簡單適配iPhoneiOS
- 記一次 Weex 的 iPhone X 適配iPhone
- iOS開發-當APP涉及到使用者敏感資訊適配Xcode9及(ios11)iOSAPPXCode
- iOS11適配遇到的問題iOS
- 微信小程式吸底區域適配iPhone X微信小程式iPhone
- [貝聊科技]貝聊 iPhone X 適配實戰iPhone
- ios11 劉海屏 安全區域 適配 彈框區域適配iOS
- 適配iPhone XR/iPhone XS MaxiPhone
- 小程式中吸底按鈕適配 iPhone X 方案iPhone
- 適配iPhone X Push過程中TabBar位置上移iPhonetabBar
- iphone 適配的sdkiPhone
- iphoneX適配iPhone
- WebView iPhoneX適配WebViewiPhone
- H5 頁面適配iPhone X,就是那麼簡單H5iPhone
- 適配iOS11, Xcode 9遇到的問題iOSXCode
- iphoneX,XsMax適配iPhone
- iOS 11 & iPhoneX 適配iOSiPhone
- iPhoneX簡單適配iPhone
- iPhone裝置適配(更新中·····)iPhone
- 第九篇:swift4.0、iPhone X、iOS 11的適配工作SwiftiPhoneiOS
- iPhone X 適配手Q H5 頁面通用解決方案iPhoneH5
- 三步適配iPhoneXiPhone
- 適配iOS11 UITableview UICollectionView MJRefresh下拉重新整理錯亂iOSUIView
- 觸手iPhoneX適配實戰iPhone
- 適配iOS 11和iPhoneX螢幕適配遇到的一些坑iOSiPhone