記錄一下iOS各個系統(tǒng)版本的適配點
整理一下iOS各個系統(tǒng)的適配版本,以下文章只做記錄整理用,有些是筆者遇到的蛋逾,有些是參考網上整理的凝垛,因為有些適配的點筆者并沒有使用到懊悯,因此也沒實際適配,最好遇到的點都自己驗證一下梦皮。
iOS11需要適配的點
1. ios11新增新的左滑刪除方法炭分,支持圖片和文字樣式
// Swipe actions
// These methods supersede -editActionsForRowAtIndexPath: if implemented
// return nil to get the default swipe actions
- (nullable UISwipeActionsConfiguration *)tableView:(UITableView *)tableView leadingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(tvOS);
- (nullable UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(tvOS);
2. UIScrollView、UITableView剑肯、UICollectionView導航偏移問題
滾動視圖在被Navigation捧毛、TabBar遮住的時候,系統(tǒng)默認會修改滾動視圖的contentInset
屬性让网,如果用戶設置滾動視圖的contentInsetAdjustmentBehavior
屬性為.never
呀忧,則系統(tǒng)不會再做相關處理。一般我們都自己處理滾動視圖的布局frame, 默認滾動視圖在導航欄下及TabBar上溃睹,因此都需要寫上
tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
iOS12需要適配的點
1. library not found for -lstdc++.6.0.9
蘋果在Xcode10 和 iOS 12中移除了 libstdc++
庫而账,由libc++
這個庫取而代之
解決方案:
一般會報此錯誤的都是舊版本的SDK庫問題,可以刪除那個庫或者從Xcode9中復制-lstdc++.6.0.9到Xcode10中
/// 模擬器
Xcode 10:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/
Xcode 11:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/
/// 真機
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib/
2. iOS 12系統(tǒng)WiFi
獲取SSID
(wifi名稱)和BSSID
(mac地址)失敗
iOS 12系統(tǒng)WiFi
獲取SSID
(wifi名稱)和BSSID
(mac地址)失敗, 在iOS 12
系統(tǒng)之后丸凭,蘋果提升了獲取WiFi
名稱和mac
地址的權限控制福扬,要獲取這些信息,需要手動為應用打開獲取WiFi信息的權限惜犀。具體操作可以參考《獲取iOS設備WiFi名字和mac地址+iOS12系統(tǒng)獲取失敗解決》铛碑。
解決方案:
在開發(fā)者賬號中,勾選項目的App ID
的Access WiFi Infomation
選項虽界;
在Xcode的Capabilities
中汽烦,勾選項目的Access WiFi Infomation
選項。
3. webView播放視頻返回后狀態(tài)欄消失
視頻播放完成主window
成為KeyWindow
的時候仍隱藏著UIStatusBar
莉御。
解決方案:
- (void)videoPlayerFinishedToShowStatusBar {
if (@available(iOS 12.0, *)) {
[[NSNotificationCenter defaultCenter] addObserverForName:UIWindowDidBecomeKeyNotification object:self.window queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
}];
}
}
iOS13需要適配的點
1. 深色模式的適配
iOS13新增了深色模式撇吞,如果項目中禁止深色模式俗冻,需要在Info.plist
添加,否則深色主題下牍颈,項目中系統(tǒng)控件背景色變成黑色背景了迄薄。
2. 模態(tài)彈出全屏和卡片樣式
iOS13的模態(tài)彈出模式并不是全屏樣式了,如果需要模態(tài)依然都是iOS13之前的樣式煮岁,需要添加
vc.modalPresentationStyle = UIModalPresentationFullScreen; 這樣模態(tài)彈出就和之前一樣了讥蔽。
3. Sign In with Apple
如果你的應用包含三方登錄方式,比如QQ画机、微信..., 那么你的應用必須包含AppID登錄冶伞,否則應用上架將會被拒。
4. 私有屬性的修改
在 iOS 13 中不再允許使用 valueForKey步氏、setValue:forKey: 等方法獲取或設置私有屬性响禽,雖然編譯可以通過,但是在運行時會直接崩潰荚醒,并提示一下崩潰信息
/// 使用的私有方法
[self.textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];
/// 崩潰提示信息
*** Terminating app due to uncaught exception 'NSGenericException', reason: 'Access to UITextField's _placeholderLabel ivar is prohibited. This is an application bug'
替換方案
/// 修改UITextField的placeholder字體大小及顏色
NSMutableAttributedString *arrStr = [[NSMutableAttributedString alloc]initWithString:self.valueTextField.placeholder attributes:@{NSForegroundColorAttributeName : UIColorFromRGB(0xD8D8D8),NSFontAttributeName:UIDEFAULTFONTSIZE(12)}];
self.valueTextField.attributedPlaceholder = arrStr;
一般盡量不要在項目中訪問系統(tǒng)的私有屬性芋类,如果使用的話,可以添加個分類交換KVC方法來處理KVC底層遍歷訪問key邏輯中的崩潰點
- (void)setNilValueForKey:(NSString *)key {
NSLog(@"[<%@ %p> setNilValueForKey]: could not set nil as the value for the key length.", self.class, self);
}
- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
NSLog(@"[<%@ %p> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key %@.", self.class, self, key);
}
- (id)valueForUndefinedKey:(NSString *)key {
NSLog(@"[<%@ %p> valueForUndefinedKey:]: this class is not key value coding-compliant for the key: %@", self.class, self, key);
return nil;
}
5. UISearchBar的黑線處理問題
之前為了處理搜索框的黑線問題腌且,通常會遍歷 searchBar 的 subViews梗肝,找到并刪除 UISearchBarBackground
。
for (UIView *view in searchBar.subviews.lastObject.subviews) {
if ([view isKindOfClass:NSClassFromString(@"UISearchBarBackground")]) {
[view removeFromSuperview];
break;
}
}
在 iOS13 中這么做會導致 UI 渲染失敗铺董,然后直接崩潰巫击,崩潰信息如下:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Missing or detached view for search bar layout'
可以使用以下方式處理黑線
// [searchBar setBackgroundImage:[UIImage new]];
UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(50, 300, kScreenW - 100, 60)];
[searchBar setBackgroundImage:[UIImage new]];
[self.view addSubview:searchBar];
6. LaunchImage 被棄用
iOS 8 之前我們是在LaunchImage
來設置啟動圖,每當蘋果推出新的屏幕尺寸的設備精续,我們需要 assets 里面放入對應的尺寸的啟動圖坝锰,這是非常繁瑣的一個步驟。因此在 iOS 8 蘋果引入了 LaunchScreen
重付,可以直接在 Storyboard 上設置啟動界面樣式顷级,可以很方便適配各種屏幕。
需要注意的是确垫,蘋果在 Modernizing Your UI for iOS 13 section 中提到 弓颈,從2020年4月開始,所有支持 iOS 13 的 App 必須提供 LaunchScreen.storyboard
删掀,否則將無法提交到 App Store 進行審批翔冀。
使用 LaunchScreen.storyboard
設置啟動頁,棄用 LaunchImage
披泪。
iOS14需要適配的點
1. 照片權限新增了選擇照片權限
iOS14中纤子,選擇照片權限使用戶允許應用訪問部分照片的權限。
if (@available(iOS 14.0, *)) {
status = [PHPhotoLibrary authorizationStatusForAccessLevel:PHAccessLevelReadWrite];
// iOS14 新增的選擇部分照片權限時
// 首次狀態(tài)之后,部分照片權限走這里
if (status == PHAuthorizationStatusLimited) {
if (completion) {
// 若允許部分照片權限控硼,即僅僅存圖片可用此權限 為YES泽论,否則為NO
completion(YES);
}
return;
}
}
2. UITableView contentView
iOS14中,UITableViewCell上的控件直接添加到cell上卡乾,點擊事件將被contentView擋住翼悴,因此,不管是否有點擊事件说订,cell上的控件都需要添加到self.contentView上抄瓦。
3. 獲取唯一標識符 API 廢棄
在 iOS13 及以前潮瓶,系統(tǒng)會默認為用戶開啟允許追蹤設置陶冷,我們可以簡單的通過代碼來獲取到用戶的 IDFA 標識符。
if ([[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled]) {
NSString *idfaString = [[ASIdentifierManager sharedManager] advertisingIdentifier].UUIDString;
NSLog(@"%@", idfaString);
}
iOS 14 以后毯辅,會默認關閉廣告追蹤權限埂伦,而且上面判斷是否開啟權限的方法已經廢棄。
解決方案: 需要我們需要在 Info.plist 中配置" NSUserTrackingUsageDescription " 及描述文案思恐,接著使用 AppTrackingTransparency 框架中的 ATTrackingManager 中的 requestTrackingAuthorizationWithCompletionHandler 請求用戶權限沾谜,在用戶授權后再去訪問 IDFA 才能夠獲取到正確信息。
#import <AppTrackingTransparency/AppTrackingTransparency.h>
#import <AdSupport/AdSupport.h>
- (void)testIDFA {
if (@available(iOS 14, *)) {
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
if (status == ATTrackingManagerAuthorizationStatusAuthorized) {
NSString *idfaString = [[ASIdentifierManager sharedManager] advertisingIdentifier].UUIDString;
}
}];
} else {
// 使用原方式訪問 IDFA
}
}
4. 定位問題
在 iOS13 及以前胀莹,App 請求用戶定位授權時為如下形態(tài):一旦用戶同意應用獲取定位信息基跑,當前應用就可以獲取到用戶的精確定位。
iOS14 新增用戶大致位置選項可供用戶選擇描焰,原因是大多數 App 實際上并不需要獲取用戶到用戶最準確的定位信息媳否。iOS14 授權彈窗新增的 Precise的開關默認會選中精確位置。用戶通過這個開關可以進行更改荆秦,當把這個值設為 On 時篱竭,地圖上會顯示精確位置;切換為Off時步绸,將顯示用戶的大致位置掺逼。
對于對用戶位置敏感度不高的 App 來說,這個似乎無影響瓤介,但是對于強依賴精確位置的 App 適配工作就顯得非常重要了吕喘。可以通過用戶在 “隱私設置” 中設置來開啟精確定位刑桑,但是可能用戶寧可放棄使用這個應用也不愿意開啟氯质。這個時候,iOS14 在 CLLocationManager 新增兩個方法可用于向用戶申請臨時開啟一次精確位置權限漾月。
- (void)requestTemporaryFullAccuracyAuthorizationWithPurposeKey:(NSString *)purposeKey completion:(void(^ _Nullable)(NSError * _Nullable))completion API_AVAILABLE(ios(14.0), macos(11.0), watchos(7.0), tvos(14.0));
/*
* requestTemporaryFullAccuracyAuthorizationWithPurposeKey:
*
* Discussion:
* This is a variant of requestTemporaryAccurateLocationAuthorizationWithPurposeKey:completion:
* which doesn't take a completion block. This is equivalent to passing in a nil
* completion block.
*/
- (void)requestTemporaryFullAccuracyAuthorizationWithPurposeKey:(NSString *)purposeKey API_AVAILABLE(ios(14.0), macos(11.0), watchos(7.0), tvos(14.0));
5. 相機和錄音
iOS14 中 App 使用相機和麥克風時會有圖標提示以及綠點和黃點提示病梢,并且會顯示當前是哪個 App 在使用此功能。我們無法控制是否顯示該提示。
6. KVC 方法禁用
如同 iOS 13 時蜓陌,UITextField 禁止使用 setValue:forKey: 來設置 _placeholderLabel 私有屬性觅彰,iOS 14 中,UIPageControl 也禁止使用 setValue 方法钮热,來設置 _pageImage 和 _currentPageImage 屬性填抬。否則運行時將會崩潰。
iOS15需要適配的點
1. iOS導航欄背景顏色設置失效處理
// 關于navigationBar背景圖片失效的問題:
if (@available(iOS 15.0, *)) {
UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init];
appearance.backgroundImage = [UIImage imageNamed:@""];
appearance.backgroundImageContentMode = UIViewContentModeScaleAspectFill;
self.navigationBar.standardAppearance = appearance;
} else {
[self.navigationBar setBackgroundImage:[UIImage imageNamed:@""] forBarMetrics:UIBarMetricsDefault];
}
/// 關于navigationBar背景顏色更改及文字大小隧期、顏色修改:
if (@available(iOS 15.0, *)) {
UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init];
[appearance configureWithOpaqueBackground];
NSDictionary *normalTextAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
[UIColor whiteColor],
NSForegroundColorAttributeName,
UIDEFAULTFONTSIZE(18),
NSFontAttributeName,
nil];
appearance.titleTextAttributes = normalTextAttributes;
appearance.backgroundColor = [UIColor orangeColor]; // 設置導航欄背景色
appearance.shadowImage = [UIImage imageWithColor:[UIColor clearColor]]; // 設置導航欄下邊界分割線透明
self.navigationBar.scrollEdgeAppearance = appearance; // 帶scroll滑動的頁面
self.navigationBar.standardAppearance = appearance; // 常規(guī)頁面飒责。描述導航欄以標準高度顯示時要使用的外觀屬性。
} else {
[self.navigationBar setBackgroundImage:[UIImage imageWithColor:[UIColor clearColor]] forBarMetrics:UIBarMetricsDefault];
// 導航欄文字
NSDictionary *normalTextAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
[UIColor whiteColor],
NSForegroundColorAttributeName,
UIDEFAULTFONTSIZE(18),
NSFontAttributeName,
nil];
[self.navigationBar setTitleTextAttributes:normalTextAttributes];
self.navigationBar.barTintColor = [UIColor orangeColor];
// 默認不透明
self.navigationBar.translucent = NO;
// 著色仆潮,讓返回按鈕圖片渲染為白色
self.navigationBar.tintColor = [UIColor whiteColor];
}
2. iOS TabBar處理同NavigationBar
if (@available(iOS 15.0, *)) {
NSDictionary* normalTextAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
UIColorFromRGB(0xA0A0A0),
NSForegroundColorAttributeName,
UIDEFAULTFONTSIZE(10),
NSFontAttributeName,
nil];
NSDictionary *selectTextAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
UIColorFromRGB(0X308014),
NSForegroundColorAttributeName,
UIDEFAULTFONTSIZE(10),
NSFontAttributeName,
nil];
UITabBarAppearance *barAppearance = [[UITabBarAppearance alloc] init];
barAppearance.backgroundColor = UIColorFromRGB(0xF5F5F5);
barAppearance.shadowImage = [UIImage imageWithColor:UIColorFromRGB(0xEEEEEE)];
// 如果是隱藏系統(tǒng)導航欄宏蛉,自定義導航欄的話,initTabBar方法中設置選中字體顏色在 iOS15同樣生效性置,若用了系統(tǒng)導航欄拾并,iOS15則需要如下方法設置tabBar字體顏色
barAppearance.stackedLayoutAppearance.normal.titleTextAttributes = normalTextAttributes;
barAppearance.stackedLayoutAppearance.selected.titleTextAttributes = selectTextAttributes;
self.tabBar.scrollEdgeAppearance = barAppearance;
self.tabBar.standardAppearance = barAppearance; // 與nav同理
/**
背景圖片
barAppearance.backgroundImage = [UIImage imageNamed:@""];
barAppearance.backgroundImageContentMode = UIViewContentModeScaleAspectFill;
self.tabBar.standardAppearance = barAppearance;
*/
} else {
[[UITabBar appearance] setBarTintColor:UIColorFromRGB(0xF5F5F5)];//這樣寫才能達到效果。
[UITabBar appearance].translucent = NO;// 這句表示取消tabBar的透明效果鹏浅。
/**
背景圖片
[[UITabBar appearance] setBackgroundImage:[UIImage imageNamed:@""]];
[UITabBar appearance].translucent = NO;
*/
}
3. UITableView新增TopPadding高度
從 iOS 15 開始嗅义,增加sectionHeaderTopPadding屬性,TableView如果是plain類型隐砸,一旦實現了viewForHeaderInSection及heightForHeaderInSection方法之碗,如果沒有設置sectionHeaderTopPadding為0,默認情況sectionHeaderTopPadding會有22個像素的高度季希。一般我們需要禁止褪那。
if (@available(iOS 15.0, *)) {
_mineTableView.sectionHeaderTopPadding = 0;
}
4. UIImageWriteToSavedPhotosAlbum
在iOS15中,UIImageWriteToSavedPhotosAlbum存儲圖片之后的回調不再返回圖片了胖眷,會返回nil
UIImageWriteToSavedPhotosAlbum(image,self,@selector(image:didFinishSavingWithError:contextInfo:), NULL);
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{
}
總結
暫時先整理這些武通,有遇到后續(xù)再補充。
參考鏈接
https://github.com/cy920820/Libstdc-.6.0.9-files lstdc++.6.0.9適配
https://juejin.cn/post/6844903792958423053 iOS12適配及兼容問題解決
http://www.reibang.com/p/1803bd950b90 iOS14 隱私適配及部分解決方案
https://juejin.cn/post/6912339107268329485 iOS 14 適配
http://www.reibang.com/p/3e1f0ce35bd5 iOS15 適配相關