iOS 11 & iPhoneX 適配
一、safeArea
automaticallyAdjustsScrollViewInsets
tocontentInsetAdjustmentBehavior
在iOS 11中,蘋果廢棄了UIViewController
的automaticallyAdjustsScrollViewInsets
屬性,改用UIScrollView
的contentInsetAdjustmentBehavior
屬性來替換它。
// OC
@property(nonatomic,assign) BOOL automaticallyAdjustsScrollViewInsets API_DEPRECATED_WITH_REPLACEMENT("Use UIScrollView's contentInsetAdjustmentBehavior instead" , ios(7.0,11.0),tvos(7.0,11.0)); // Defaults to YES
//swift
@available(iOS, introduced: 7.0, deprecated: 11.0)
open var automaticallyAdjustsScrollViewInsets: Bool // Defaults to YES
如果你的工程中沒有新增 iPhone X
對應的啟動圖,你會發現頂部和底部的一部分都是黑色的,那部分就是安全域。
想要對 iPhone X
做螢幕適配,第一步先要新增啟動圖。
二、UITableView
自動計算高度
在iOS 11中,UITableView
estimatedRowHeight
、 estimatedSectionHeaderHeight
、 estimatedSectionFooterHeight
預設都是開啟的。真是令人驚喜。
@property (nonatomic) CGFloat rowHeight; // default is UITableViewAutomaticDimension
@property (nonatomic) CGFloat sectionHeaderHeight; // default is UITableViewAutomaticDimension
@property (nonatomic) CGFloat sectionFooterHeight; // default is UITableViewAutomaticDimension
@property (nonatomic) CGFloat estimatedRowHeight NS_AVAILABLE_IOS(7_0); // default is UITableViewAutomaticDimension, set to 0 to disable
@property (nonatomic) CGFloat estimatedSectionHeaderHeight NS_AVAILABLE_IOS(7_0); // default is UITableViewAutomaticDimension, set to 0 to disable
@property (nonatomic) CGFloat estimatedSectionFooterHeight NS_AVAILABLE_IOS(7_0); // default is UITableViewAutomaticDimension, set to 0 to disable
踩坑1
在我們的app中,首頁的 UITableView
列表是手動計算的行高,突然出現了以往只有開啟自動計算行高才會出現的滾動條跳動的現象,給 TableView
的 contentSize
加了observer
,果然一直在變。然後在這裡找到了原因。
踩坑2 (更新)
在使用 MJRefersh
的時候,本身程式碼存在一個 bug
,原來並沒有發現,iOS 11 幫我發現了這個問題。
// tableView 設定
let footer = MJRefreshAutoFooter(refreshingBlock: { [weak self] in
if let strongSelf = self {
if let block = strongSelf.footerBlock {
block()
}
}
})
footer?.triggerAutomaticallyRefreshPercent = -20
tableView.mj_footer = footer
// 請求結束後處理(錯誤)
models.append(requestModels)
if models.count < pageSize { // 這裡是個bug
tableView.mj_footer.endRefreshingWithNoMoreData()
} else {
tableView.mj_footer.state = .idle
}
tableView.reloadData()
// 請求結束後處理(正確)
if requestModels.count < pageSize { // 修復bug
tableView.mj_footer.endRefreshingWithNoMoreData()
} else {
tableView.mj_footer.state = .idle
}
models.append(requestModels)
tableView.reloadData()
上面程式碼中,在 iOS 11
之前也存在隱含的問題,就是 tableView footer
一直不能被標記為 無更多資料
的狀態,即使沒有資料了,使用者下拉依然後發起請求。
在 iOS 11
中,由於估算行高,互動到底部時,依然會觸發 tableView
的 contentSize
和 contentOffset
變化,同時會觸發 refreshingBlock
, 和 tableView
的 reloadData
,導致了最後一頁資料陷入了迴圈請求。
引申問題
如果存在使用監聽 tableView
的 contentSize
和 contentOffset
變化來觸發的一些事件,最好把 tableView
的自動計算行高關掉,以免出現問題。
三、iPhone X***(嚴重)*
1. 狀態列獲取網路狀態
眾所周知,iPhone X多了個“美美的”劉海,它的狀態列發生了變化。這也導致了原來從狀態列檢視獲取網路狀態的API出了問題,會導致閃退。
// 獲取當前app狀態列子檢視
UIApplication *app = [UIApplication sharedApplication];
NSArray *children = [[[app valueForKeyPath:@"statusBar"] valueForKeyPath:@"foregroundView"] subviews];
int type = 0;
for (id child in children) {
if ([child isKindOfClass:NSClassFromString(@"UIStatusBarDataNetworkItemView")]) {
type = [[child valueForKeyPath:@"dataNetworkType"] intValue];
}
}
switch (type) {
case 1:
return @"2G";
case 2:
return @"3G";
case 3:
return @"4G";
case 5:
return @"WIFI";
default:
return @"Unknow";
break;
}
不過你依然可以用AFNetworking
類似的方式,獲取網路狀態:
SCNetworkReachabilityContext context = {0, (__bridge void *)callback, AFNetworkReachabilityRetainCallback, AFNetworkReachabilityReleaseCallback, NULL};
SCNetworkReachabilitySetCallback(self.networkReachability, AFNetworkReachabilityCallback, &context);
SCNetworkReachabilityScheduleWithRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
switch (self.networkReachabilityAssociation) {
case AFNetworkReachabilityForName:
break;
case AFNetworkReachabilityForAddress:
case AFNetworkReachabilityForAddressPair:
default: {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),^{
SCNetworkReachabilityFlags flags;
SCNetworkReachabilityGetFlags(self.networkReachability, &flags);
AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusForFlags(flags);
dispatch_async(dispatch_get_main_queue(), ^{
callback(status);
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter postNotificationName:AFNetworkingReachabilityDidChangeNotification object:nil userInfo:@{ AFNetworkingReachabilityNotificationStatusItem: @(status) }];
});
});
}
break;
}
static AFNetworkReachabilityStatus AFNetworkReachabilityStatusForFlags(SCNetworkReachabilityFlags flags) {
BOOL isReachable = ((flags & kSCNetworkReachabilityFlagsReachable) != 0);
BOOL needsConnection = ((flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0);
BOOL canConnectionAutomatically = (((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) || ((flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0));
BOOL canConnectWithoutUserInteraction = (canConnectionAutomatically && (flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0);
BOOL isNetworkReachable = (isReachable && (!needsConnection || canConnectWithoutUserInteraction));
AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusUnknown;
if (isNetworkReachable == NO) {
status = AFNetworkReachabilityStatusNotReachable;
}
#if TARGET_OS_IPHONE
else if ((flags & kSCNetworkReachabilityFlagsIsWWAN) != 0) {
status = AFNetworkReachabilityStatusReachableViaWWAN;
}
#endif
else {
status = AFNetworkReachabilityStatusReachableViaWiFi;
}
return status;
}
2.狀態列
- 狀態列高度由原來的20,變為44了,以前使用常量的就被坑了。
- 在修改我們的巨集過程中遇到了另外一個坑,特此提醒:
// 原有
#define MPStatusBarHeight (20)
// 新的
#define MPStatusBarHeight (UIApplication.sharedApplication.statusBarFrame.size.height)
/* 坑在此處 */
// application 的 statusBarFrame 在隱藏狀態列的時候是 CGRectZero
@property(nonatomic,readonly) CGRect statusBarFrame __TVOS_PROHIBITED; // returns CGRectZero if the status bar is hidden
3.友盟分享
友盟分享 SDK 6.4.6 版本提供的介面沒有適配 iPhone X
需要更新 SDK
到最新的 6.8.0 版本,很遺憾的是,目前最新的友盟所有產品都沒有提供 cocoapods
版本,需要手動整合。
在整合過程中遇到一個坑:
由於我們工程同時使用 pod
引用了友盟分享和友盟統計,本來只想升級友盟分享,於是直接跳到整合友盟分享的文件部分,執行了下面的操作:
1、移除pod對 UMShare的引用,執行 pod install
2、新增UMShareSDK到工程
3、修改檔案引用錯誤
4、清除DerivedData
5、在模擬器build
報錯:
詢問了友盟客服(馬上就回復了,很給力),是由於沒有整合 common
基礎庫,回過頭來看文件,發現整合友盟任意庫都需要加入 common
基礎庫。
但是一旦加入 common
基礎庫,又會和使用 pod
引用的友盟統計衝突,無奈,只能統計庫和分享庫都換成手動引用。
四、UIToolBar
在 UIToolBar
中兩側添加了 UIBarButtonItem
,在 iOS 11
之前會佈局在邊,在 iOS 11
中兩個item是緊挨著的,需要在中間新增 UIBarButtonSystemItemFlexibleSpace
型別的 item
才可以。
五、ALAssetsLibrary
儲存圖片閃退
在 iOS 11 之前,你可以直接使用下面程式碼來儲存圖片到相簿:
#import <AssetsLibrary/AssetsLibrary.h>
// ALAssetsLibrary
[[[ALAssetsLibrary alloc] init] writeImageDataToSavedPhotosAlbum:imageData metadata:nil completionBlock:^(NSURL *assetURL, NSError *error) {
[self saveResultWithResult:(error == nil)];
}];
在 iOS 11中則會直接崩潰,儲存圖片的新姿勢:
- 解決方案1:
在 infoPlist 檔案中追加相簿寫入許可權的提示
引數 | key | Xcode name | 版本 | 說明 |
---|---|---|---|---|
NSPhotoLibraryAddUsageDescription | “Privacy - Photo Library Additions Usage Description” | Specifies the reason for your app to get write-only access to the user’s photo library. See NSPhotoLibraryAddUsageDescription for details. | iOS 11 and later | 本引數iOS 11必須追加 |
NSPhotoLibraryUsageDescription | “Privacy - Photo Library Usage Description” | Specifies the reason for your app to access the user’s photo library. See NSPhotoLibraryUsageDescription for details. | iOS 6.0 and later | 本引數iOS 10以後必須追加 |
在infoPlist中直接新增(xcode 中 open as Source Code):
<key>NSPhotoLibraryUsageDescription</key>
<string>此 App 需要您的同意才能讀取媒體資料庫</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>此 App 需要您的同意才能寫入媒體資料庫</string>
解決方案2:
~~如果沒有按方案1新增寫入許可權提示,ALAssetsLibrary
寫入直接崩潰,而PHPhotoLibrary
儲存圖片會直接觸發向用戶請求相簿寫入許可權的 Alert 提示。~~
#import <Photos/Photos.h>
// PHPhotoLibrary
- (void)saveImageByPHPhotoLibrary:(UIImage *)image {
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
[PHAssetCreationRequest creationRequestForAssetFromImage:image];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
[self saveResultWithResult:(success && error == nil)];
});
}];
}
更新
由於在應用中使用了 WKWebView
, WKWebView
在沒有處理的情況下,長按圖片會彈出儲存圖片的選項,選擇儲存圖片同樣會崩潰。所以該方案不能處理好所有入口,推薦使用方案1。
- 解決方案3:
更為合理的做法是,在向相簿寫入圖片之前,首先請求相簿許可權,參考iOS相簿、相機、通訊錄許可權獲取
六、鍵盤鑰匙串 (password auto fill)
1、問題
在iOS 11系統中,你會發現你原本的一些輸入框喚起系統鍵盤後出現如下的狀況:
鍵盤右上角的��,是iOS 11的新特性 Password Auto Fill
,假如你在程式碼中設定 UITextField
的 contentType 為 username
和 password
型別,就會出現上面的圖示。
usernameTextField.textContentType = UITextContentType.username
passwordTextField.textContentType = UITextContentType.password
而有些情況,在 XIB
檔案中,如果你沒有指定特定型別,鍵盤也會出現��:
對應情況你只需要將 contentType
設定為其它型別即可:
2、關於 Password Auto Fill
七、react-native
可以參考下面程式碼,來適配狀態列和底部安全域:
import { Dimensions, Platform } from 'react-native'
const { width, height } = Dimensions.get('window')
export const isIphoneX = () => (
Platform.OS === 'ios' &&
!Platform.isPad &&
!Platform.isTVOS &&
(height === 812 || width === 812)
)
const getStatusBarHeight = () => {
if (Platform.OS === 'android') {
return 0
}
if (isIphoneX()) {
return 44
}
return 20
}
// const
export const IPHONEX_BOTTOM_HEIGHT = 34
export const STATUSBAR_HEIGHT = getStatusBarHeight()
相關推薦
iOS 11 & iPhoneX 適配
一、safeArea automaticallyAdjustsScrollViewInsets to contentInsetAdjustmentBehavior 在iOS 11中,蘋果廢棄了 UIViewController 的automatically
ios 11 螢幕適配問題!
隨著Xcode GM版本釋出,適配iOS 11也就提上了日程,總的來說整個適配過程(不包含適配iPhone X)不是很麻煩。 首先建議觀看今年WWDC的一個視訊 Updating Your App for iOS 11,視訊講解了iOS 11一些API的變化,對
iOS 採用@available(iOS 11.0, *)適配 iOS11,會引起呼叫系統相簿時,系統介面上移問題
我們在使用以下方法適配 iOS11,避免滾動檢視頂部出現20的空白以及push或者pop的時候頁面有一個上移或者下移的異常動畫的問題時,會導致一個問題,就是當我們的應用呼叫系統相簿時,引起系統相簿介面整體上移。原因是因為:全域性設定瞭如下的方法。 if (@a
<iOS屏幕適配> iPhoneX SafeArea - 安全區域
sub 分享 ace 了解 ati 屏幕寬度 tool 圖的創建 結果 一. 前言 p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px "PingFang SC"; color: #000000 } span.s1 {
iOS iPhoneX 適配
1.導航欄高度 88 非非IPoneX手機為64 2.狀態列高度44 非IPoneX手機為20 3.tabar高度83 非IPhoneX手機為49 如下圖所示; 問題:push時tabbar向上移動導致一塊小黑螢幕 簡單描述一下,這就是一個蘋果官方開發人員的一個
iOS開發之適配iOS11&iPhoneX的一些坑
導航欄 導航欄高度的變化 iOS11之前導航欄預設高度為64pt(這裡高度指statusBar + NavigationBar),iOS11之後如果設定了prefersLargeTitles = YES則為96pt,預設情況下還是64pt,但在iP
【IOS開發】iPhoneX適配 wkWebView螢幕下方有間隙的問題
在iPhoneX適配時,wkWebView會出現螢幕下方有一定間距的情況,大約是螢幕底部到安全區(safe area)的距離。此時可以用以下方法解決。 if(@available(iOS 11.0,
iOS屏幕適配方案-Auto Layout
board for intro post 用戶 this 沒有 ber ios控件 市場上的android手機五花八門。各種尺寸的屏幕讓android程序員們比較頭疼。也有一些大神寫了一些博客提出了自己的觀點。iOS貌似也迎來了大屏6+,因此屏幕適配的問
iphoneX適配!!!
color kit 底部導航 AD width 所在 pan 參數 -s 方法1.js判斷(以下采用Jquery) //適配iphonex if($(window).width() === 375 && $(window).height() === 7
【iOS】螢幕適配
螢幕適配 1、螢幕適配的發展過程: 程式碼計算frame -> autoreszing(父控制元件和子控制元件的關係) -> autolayout(任何控制元件都可以產生關係) -> sizeclass 沒有螢幕適配,直接使用frame固定子控制元件的
三款新iPhone劉海屏沒跑了!蘋果要求iOS APP必須適配
原標題:三款新iPhone劉海屏沒跑了!蘋果要求iOS APP必須適配 2017年蘋果最重磅的新品就 2017年蘋果最重磅的新品就是iPhone X了。可從外形的角度,由於頂部“劉海”的存在,距離完美的全面屏還差一截。 同時,這種異形切割的設計也對iOS軟體的適配帶來了挑戰和提
劉海屏繼續!蘋果要求iOS App必須適配
中關村線上訊息:若說去年最火的,應該是所有人都會想到的。不過由於劉海屏的外觀設計,距離真正的全面屏手機還是有很長一段距離要走。不過,這種異形屏對iOS的適配帶來了挑戰和提出新要求,即便蘋果很早就給出了文件,幫助開發者快速調整,然而進度似乎並不令人滿意。 劉海屏設計 今天根據外媒
iOS 9 HTTPS適配
Xcode 7.0也就是iOS9.0中開發要求App內訪問的網路必須使用HTTPS協議。那麼我們公司沒用採用https怎麼辦?如果發現網路請求失敗,Xcode後臺報錯資訊為: The resource could not be loaded because the App
iOS ---【開發適配iPhone XS, iPhone XS Max, iPhone XR】
總結為以下幾點: 一、 螢幕大小適配 三款手機,分別是iPhone XS,iPhone XR,iPHone X Max,其中iPhone XS的螢幕尺寸和iPhone X的是一致的,另外兩款都有了新的尺寸,具體尺寸如下 具體原理性的東西就多說了,因為
iOS XIB約束適配 || 字型 根據螢幕寬變化
簡單實現XIB上的約束值,按照指定需求自動變化(根據螢幕寬度變化)。 基準圖(750 * 1334)上控制元件距離左邊為20 達到效果:5s(640 * 1136)上執行距離為 20*(320/375.0) = 17.07; 6s(750 * 1334)上執行距離為 2
iOS 12釋出前,蘋果宣佈:7月起,iOS App必須適配iPhone X劉海屏
5月8日訊息在微軟和谷歌召開開發者大會之際,蘋果官方今天宣佈,從7月份開始,所有iOS App更新必須使用iOS 11 SDK構建,並且必須支援iPhone X的超級視網膜顯示器,當然也包括適配劉海屏。 蘋果表示,藉助iOS 11 SDK,應用
apicloud針對iPhoneX適配問題
1、iPhoneX啟動圖尺寸為1125*2436 若未上傳對應的iPhone X啟動圖或者啟動圖格式不正確,應用執行在iPhone X上面時上下將有大黑邊,不能全屏執行。 2、狀態列高度不再是以前的20px,而是變成了44px,如果應用開啟了沉浸式效果,那麼頁面
iOS iPhone X適配
IPhoneX 導航欄 狀態列 tabar高度 1.導航欄高度 88 非IPhoneX手機為64 2.狀態列高度 44 非IPhoneX手機為20 3.tabar高度 83 非IPhoneX手機為49 如下圖所示: //判斷iPhone X #defi
iOS字型大小適配的幾種方法
在iOS開發中,有些公司對字型也有適配要求,為了讓字型美觀,所以在不同尺寸的螢幕上字型大小也要做到適配。 自己總結了幾種方法供大家參考。 方法一:用巨集定義適配字型大小(根據螢幕尺寸判斷) //巨集定義 #define SCREEN_WIDTH ([UIScreen mainScreen].
【iOS】螢幕適配之NSLayoutConstraint
import Foundationclass NSLayoutConstraintEx: NSLayoutConstraint { @IBInspectable var ipad: CGFloat = 0 { didSet { if DeviceUtils.is