iOS版本相容以及部分iOS 11適配
Tips Xcode 配置理解
1.Base SDK
指的是當前編譯用的SDK版本。簡單來說就是表示當前使用的Xcode所支援的最高的SDK的版本,比如現在是用iOS 11來編譯程式,那麼最高的SDK也就是11
2.Deployment Target
指的是編譯出的程式將在哪個系統版本上執行,它控制著執行應用需要的最低作業系統版本。簡單來說是當前的設定的Target所支援的最低的iOS的版本,比如現在設定的8.0,那麼最低執行適配版本就是8.0,再低可能就炸了
版本相容面對的問題
1.若你想要體驗最新的iOS 11的功能,又要相容iOS 8.0版本,Base SDK設定為最新的iOS 11(預設即可)。Deployment Target設定為iOS 8.0。當然,你用到的iOS 11 的API,要確保它們不會在iOS 8.0上不會crash。
2.團隊開發,如果你比較獵奇,你已經升級了最新的Xcode9,那麼你就能編譯最新的SDK,支援iOS 11,但是你的同事比較保守,沒有升級,還是停留在Xcode 8,那麼最高支援也就是iOS 10.3,當你提交了程式碼,如果不做好不同版本之間的條件編譯,會導致用舊版本Xcode同事報錯無法編譯
解決思路一:靜態檢查編譯SDK階段
靜態檢查,即在編譯時段就檢查當前SDK編譯與構建應用是否能使用某個API或已經不支援某個API
1.__IPHONE_OS_VERSION_MIN_REQUIRED
值等於Deployment Target,檢查支援的最小系統版本。
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000
//minimum deployment target is 8.0, so it’s safe to use iOS 8-only code
當前SDK最小支援的裝置系統,即8.0,所以在iOS 8.0裝置上是安全的
#else
//you can use iOS8 APIs, but the code will need to be backwards
//compatible or it will crash when run on an iOS 7 device
你仍然可以使用iOS 8的API,但是在iOS 7的裝置上可能會crash.
#endif
2.__IPHONE_OS_VERSION_MAX_ALLOWED
值等於Base SDK,即用於檢查SDK版本的
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0
//you can use iOS 11 APIs here because the SDK supports them
//but the code may still crash if run on an iOS 8 device
可以使用最新的iOS 11的API,開始支援的新功能。但是仍然可能會在iOS 8的裝置上crash。
#else
//this code can’t use iOS 10 APIs as the SDK version doesn’t support them
不能使用iOS 11的API,只能使用iOS 11之前的。
#endif
通過系統預設的巨集定義進行條件編譯
1.每次釋出新版本SDK的時候,都會伴隨新的API供大家使用,因此為了做相容,低版本還是用低版本方法,而新版本可以用高版本API來進行相容
2.巨集只在編譯階段生效,只是純粹的文字替換,被巨集包起來的程式碼,在編譯階段已經決定是否執行了,如果已經執行到系統上,那麼巨集就已經沒什麼卵用,已經在編譯階段判定好使用哪段程式碼了
3.那麼問題來了,不同版本的Xcode要進行巨集定義的條件編譯不同適配的程式碼,才能保證SDK的相容問題
#ifndef __IPHONE_11_0
#define __IPHONE_11_0 110000
#endif
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0
#else
#endif
這樣只是保證了不同SDK之間的相容問題,保證編譯的時候不存在問題,那麼跑進系統之後如何保證高版本API在低系統執行時也能相容,那麼就需要執行時檢查系統版本
解決思路二:執行時檢查系統版本
這裡從StackOverFlow上搜集了一些判斷當前系統版本的幾個方法
1.Xcode 9新方法
if (@available(iOS 11, *)) {}
如果要看available語法的介紹可以自行百度,一大把
2.NSFoundationVersionNumber
iphone版本感覺10之前都可以用,貌似10之後有點問題了,稍微知道下就好了,反正我不用
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
// here you go with iOS 7
}
3.UIDevice
if ([[ [UIDevice currentDevice] systemVersion] floatValue] >= 11.0) {
}
該方法對於整數,float計算出來就不會有問題,那麼當如果你的系統是11.2.1和11.2.2這個時候就會出現精度問題,畢竟float存在的精度問題隨時會出現,這種簡單的判斷適用於整數大版本,小版本就無法精確判斷了
4.NSOperatingSystemVersion
NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion];
NSLog(@"major--->%ld,minjor--->%ld,patch--->%ld",version.majorVersion,version.minorVersion,version.patchVersion);
NSOperatingSystemVersion v = (NSOperatingSystemVersion){9,0,0};
// 判斷作業系統是否大於等於v版本
BOOL isRight = [[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:v];
if (isRight) {
NSLog(@"當前版本大於指定版本");
}
else
{
NSLog(@"當前版本小於指定版本");
}
// 2017-09-27 15:43:01.540690+0800 測試Icon[28898:915470] major--->11,minjor--->0,patch--->0
// 2017-09-27 15:43:01.540811+0800 測試Icon[28898:915470] 當前版本大於指定版本
這種方法是iOS 8之後才有的,目前為止的話可以用了,畢竟已經最低支援iOS 8了,不用擔心7了
5.字串比較
/*
* System Versioning Preprocessor Macros
*/
#define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)
/*
* Usage
*/
if (SYSTEM_VERSION_LESS_THAN(@"4.0")) {
...
}
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"3.1.1")) {
...
}
我用的就是這種方式
但是需要注意的是,如果你係統版本是11.0,你指定的版本是11.0.0,這種情況下,你要知道11.0.0是比11.0版本大的,也就是說你用SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"11.0.0")
返回的是NO
針對上面的方法舉個例子
#ifndef __IPHONE_8_0
#define __IPHONE_8_0 80000
#endif
// 編譯時判斷:檢查SDK版本 相容Xcode版本
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0
// 執行時判斷:檢查當前系統版本
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) {
UIAlertController *alertController =
[UIAlertController alertControllerWithTitle:@"Warning"
message:@"Compatibility"
preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"Cancel"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action) {
NSLog(@"Cancel");
}]];
[self presentViewController:alertController animated:YES completion:nil];
} else {
// 用舊的代替
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Warning"
message:@"Compatibility"
delegate:nil
cancelButtonTitle:@"Cancel"
otherButtonTitles:nil];
[alertView show];
}
#else
// ...
#endif
}
針對上面提到的知識點總結,這裡老外有一個簡單的回答
總結來說:編譯時檢查SDK版本(相容Xcode),執行時檢查系統版本(相容系統)
iOS 11適配
適配詳情可以參考如下連結
iOS 11適配詳解
下面都是我個人的感覺和做法
iPhone X 變化最大的是頭部 & 底部
非iPhone X :
StatusBar 高20px,NavigationBar 高44px,底部TabBar高49px
iPhone X:
StatusBar 高44px,NavigationBar 高44px,底部TabBar高83p
來來來,一句話搞定適配,把下面的程式碼放著這個下面
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
#ifndef __IPHONE_11_0
#define __IPHONE_11_0 110000
#endif
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0
// if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"11.0")) {
if (@available(iOS 11.0, *)) {
UIScrollView.appearance.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
UITableView.appearance.estimatedRowHeight = 0;
UITableView.appearance.estimatedSectionFooterHeight = 0;
UITableView.appearance.estimatedSectionHeaderHeight = 0;
} else {
// Fallback on earlier versions
}
// }
#endif
個人的一些知識點記錄,如果對於上面提到的有任何問題,各位大神請留言指點,謝謝了~~~
參考連結
How to check iOS version?
版本相容
解決iOS專案的版本相容問題-結合巨集、Category和Runtime
相關文章
- iOS 11適配iOS
- iOS MJRefresh適配ios11以及iPhoneXiOSiPhone
- iOS11 適配iOS
- iOS 11 適配的坑iOS
- iOS11適配詳解iOS
- iPhone X + iOS 11 適配指南iPhoneiOS
- iOS 11 & iPhoneX 適配iOSiPhone
- iOS 適配低版本的方法iOS
- 適配iPhoneX & iOS11iPhoneiOS
- iOS開發 適配iOS10以及Xcode8iOSXCode
- iOS12、iOS11、iOS10、iOS9常見適配iOS
- iOS11適配遇到的問題iOS
- 適配iOS11--contentInsetAdjustmentBehavioriOS
- 《iOS 11 安全區域適配總結》iOS
- 10分鐘適配 iOS 11 & iPhone XiOSiPhone
- [iOS]適配iOS10問題iOS
- iOS14 隱私適配及部分解決方案iOS
- iOS 11 適配看這篇還不夠?iOS
- iPhone X和iOS 11的簡單適配iPhoneiOS
- ios11 劉海屏 安全區域 適配 彈框區域適配iOS
- iOS9適配TipiOS
- iOS 11適配之跳轉App Store評論iOSAPP
- iOS11, Xcode9 and iphone X適配iOSXCodeiPhone
- 隨手記 iOS 11 適配實踐總結iOS
- 開發日常 適配iOS11和iPhone XiOSiPhone
- 適配iOS 11和iPhoneX螢幕適配遇到的一些坑iOSiPhone
- 適配iOS11, Xcode 9遇到的問題iOSXCode
- iOS13簡單適配iOS
- iOS10推送通知適配iOS
- [iOS]iOS 7的Navigation適配解決方案iOSNavigation
- iOS 10 SiriKit QQ 適配詳解iOS
- 【轉】適配iOS9系統iOS
- iOS微信更新6.7.4版本:適配iPhone XS MAX大螢幕iOSiPhone
- iOS 11 適配(一)UITableViewStyleGrouped 型別 tableView sectionHeader 高度問題iOSUIView型別Header
- iOS 10 適配知識點總結iOS
- iOS10 CAAnimationDelegate 的簡單適配iOS
- iOS多解析度適配綜述iOS
- iOS10推送適配完整說明iOS