iOS 11和xcode9

最近發現了比較奇怪的問題,就是 ios10.幾之前的版本,用xcode9 編寫的程序   若是程序寫的table是  plain的  ,那麼  在  ios10.幾及如下版本都會顯示成group樣式,而在最新的ios11上倒是  plain樣式,看來蘋果作的東西不兼容了,哈哈。從沒給蘋果提過bug,不知道去哪裏提。有門路的能夠拿去提bug。固然提了後請告訴我結果。  下面就說說 ios 11 的適配。html

 

如下是我從網絡蒐集來的,供你們參考,感謝分享ios

說法一git

1.相冊權限須要增長,否則會形成閃退喲github

增長info.Plist中的字段: json

以前的這個字段:Privacy - Photo Library Usage Description xcode

須要增長這個字段Privacy - Photo Library Additions Usage Description,內容和上面字段保持一致便可。 安全

2.UITableViewStyleGrouped樣式的UITableView的sectionHeader和sectionFooter有一個默認的高度,一般不須要顯示header或者footer的時候,會這麼寫網絡

?
1
2
3
4
5
6
7
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
   return  CGFLOAT_MIN;
}
 
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
   return  CGFLOAT_MIN;
}

可是在iOS11裏面你會發現段頭段尾又回來辣!改了各類新增的屬性好比safeArea之類的一點用都沒有,最後發現必需要把estimatedSectionHeaderHeight置0才變回去app

3.在iOS11中,蘋果開放了NFC(Near field communication),怕也是其推廣ApplePay的一種策略。 
在使用近場通信時,首先也要在info.plist配置NFCReaderUsageDescription 權限,案例步驟,以下:ide

iOS 11 Core NFC - any sample code?

4.若是您在Navigation上的titleView上添加searchBar,iOS11狀況下可能有問題

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- ( void )resetSearchBar
{
   CGFloat leftButtonWidth = 35, rightButtonWidth = 75;  // left padding right padding
   UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width - leftButtonWidth - rightButtonWidth, 44)];
 
   self.searchBar.translatesAutoresizingMaskIntoConstraints = NO;
   [container addSubview:self.searchBar];
 
   CGFloat offset = (rightButtonWidth - leftButtonWidth) / 2;
   // 給searchBar添加約束
   [NSLayoutConstraint activateConstraints:@[
                        [self.searchBar.topAnchor constraintEqualToAnchor:container.topAnchor],  // 頂部約束
                        [self.searchBar.leftAnchor constraintEqualToAnchor:container.leftAnchor constant:-25*ScreenScaleX],  // 左邊距約束
                        [self.searchBar.rightAnchor constraintEqualToAnchor:container.rightAnchor constant:0],  // 右邊距約束
                        [self.searchBar.bottomAnchor constraintEqualToAnchor:container.bottomAnchor],  // 底部約束
                        [self.searchBar.centerXAnchor constraintEqualToAnchor:container.centerXAnchor constant:-offset],  // 橫向中心約束
                        //                       [self.searchBar.widthAnchor constraintEqualToAnchor:container.widthAnchor constant:width] // 寬度約束
                        ]];
   self.navigationItem.titleView = container;  // 頂部導航搜索
}

 

說法二

整個適配過程(不包含適配iPhone X)不是很麻煩。

首先建議觀看今年WWDC的一個視頻 Updating Your App for iOS 11,視頻講解了iOS 11一些API的變化,對理解適配過程有幫助。

navigation bar

一、導航欄新增了一種大標題樣式,默認設置是不開啓,因此不須要修改。

二、titleView支持autolayout,這要求titleView必須是可以自撐開的或實現了- intrinsicContentSize,簡書的搜索就變成下面這樣了

搜索

解決辦法比較簡單,這個搜索框對應的view實現- intrinsicContentSize方法

1
2
3
- (CGSize)intrinsicContentSize {
     return  UILayoutFittingExpandedSize;
}

安全區域適配

iOS 11中ViewController的automaticallyAdjustsScrollViewInsets屬性被廢棄了,致使了這兩個頁面出現了問題

這兩個頁面都隱藏了系統導航欄,自定義導航欄。

1
2
3
self.automaticallyAdjustsScrollViewInsets = NO;
self.extendedLayoutIncludesOpaqueBars = YES;
self.edgesForExtendedLayout = UIRectEdgeTop;

automaticallyAdjustsScrollViewInsets屬性被廢棄了,頂部就多了必定的inset,關於安全區域適配,簡書上的這篇文章iOS 11 安全區域適配總結介紹得很是詳細,請參考這篇文章。

咱們採用了比較簡單的方法

1
2
3
4
5
if  (@available(iOS  11.0 , *)) {
     self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
else  {
     self.automaticallyAdjustsScrollViewInsets = NO;
}

導航欄返回按鈕

以前的代碼經過下面的方式自定義返回按鈕

1
2
3
4
5
6
7
UIImage *backButtonImage = [[UIImage imageNamed:@ "icon_tabbar_back" ]
     resizableImageWithCapInsets:UIEdgeInsetsMake( 0 18 0 0 )];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonImage
                                                   forState:UIControlStateNormal
                                                barMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake( 0 , - 60 )
                                                     forBarMetrics:UIBarMetricsDefault];

iOS 11 中setBackButtonTitlePositionAdjustment:UIOffsetMake無法把按鈕移出navigation bar。

解決方法是設置navigationController的backIndicatorImage和backIndicatorTransitionMaskImage

1
2
3
UIImage *backButtonImage = [[UIImage imageNamed:@ "icon_tabbar_back" ] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
self.navigationBar.backIndicatorImage = backButtonImage;
self.navigationBar.backIndicatorTransitionMaskImage = backButtonImage;

tableview問題

右邊爲正確樣式

iOS 11中若是不實現-tableView: viewForFooterInSection: 和 -tableView: viewForHeaderInSection:,那麼-tableView: heightForHeaderInSection:和- tableView: heightForFooterInSection:不會被調用。

這是由於estimatedRowHeight estimatedSectionHeaderHeight estimatedSectionFooterHeight三個高度估算屬性由默認的0變成了UITableViewAutomaticDimension,致使高度計算不對,解決方法是實現對應方法或吧這三個屬性設爲0。

下面這個列表顯示不全也是estimatedRowHeight引發,取contentSize出錯。

第三方依賴庫問題

一、ReactiveCocoa Unknown warning group ‘-Wreceiver-is-weak’,ignored警告

ReactiveCocoa

簡書項目開啓Treat warning as error,全部警告都會被當成錯誤,所以必須解決掉。

RACObserve宏定義以下:

1
2
3
4
5
6
7
8
#define RACObserve(TARGET, KEYPATH) \
     ({ \
         _Pragma( "clang diagnostic push" ) \
         _Pragma( "clang diagnostic ignored \"-Wreceiver-is-weak\"" ) \
         __weak id target_ = (TARGET); \
         [target_ rac_valuesForKeyPath:@keypath(TARGET, KEYPATH) observer:self]; \
         _Pragma( "clang diagnostic pop" ) \
     })

在以前的Xcode中若是消息接受者是一個weak對象,clang編譯器會報receiver-is-weak警告,因此加了這段push&pop,最新的clang已經把這個警告給移除,因此不必加push&pop了。

ReactiveCocoa已經再也不維護OC版本,大多數OC開發者用的都是2.5這個版本,只能本身fork一份了,誰知github上的v2.5代碼不包含對應的.podspec文件,只好到CocoaPods/Specs上將對應的json文件翻譯成.podspec文件,若是你也有這個須要,能夠修改Podfile如

1
pod  'ReactiveCocoa' , :git =>  'https://github.com/zhao0/ReactiveCocoa.git' , :tag =>  '2.5.2'

二、MGSwipeTableCell 崩潰

左滑cell

MGSwipeTableCell用於實現左滑菜單,在iOS 11上出現了崩潰,github上新版修復了,升級便可

連接來自

http://www.cocoachina.com/ios/20170915/20580.html

==================================================

 

導航欄

導航欄高度的變化

iOS11以前導航欄默認高度爲64pt(這裏高度指statusBar + NavigationBar),iOS11以後若是設置了prefersLargeTitles = YES則爲96pt,默認狀況下仍是64pt,但在iPhoneX上因爲劉海的出現statusBar由之前的20pt變成了44pt,因此iPhoneX上高度變爲88pt,若是項目裏隱藏了導航欄加了自定義按鈕之類的,這裏須要注意適配一下。

導航欄圖層及對titleView佈局的影響

iOS11以前導航欄的title是添加在UINavigationItemView上面,而navigationBarButton則直接添加在UINavigationBar上面,若是設置了titleView,則titleView也是直接添加在UINavigationBar上面。iOS11以後,大概由於largeTitle的緣由,視圖層級發生了變化,若是沒有給titleView賦值,則titleView會直接添加在_UINavigationBarContentView上面,若是賦值了titleView,則會把titleView添加在_UITAMICAdaptorView上,而navigationBarButton被加在了_UIButtonBarStackView上,而後他們都被加在了_UINavigationBarContentView上,如圖:

 
圖1

因此若是你的項目是自定義的navigationBar,那麼在iOS11上運行就可能出現佈局錯亂的bug,解決辦法是重寫 UINavigationBarlayoutSubviews方法,調整佈局,上代碼:

 

- (void)layoutSubviews { [super layoutSubviews]; //注意導航欄及狀態欄高度適配 self.frame = CGRectMake(0, 0, CGRectGetWidth(self.frame), naviBarHeight); for (UIView *view in self.subviews) { if([NSStringFromClass([view class]) containsString:@"Background"]) { view.frame = self.bounds; } else if ([NSStringFromClass([view class]) containsString:@"ContentView"]) { CGRect frame = view.frame; frame.origin.y = statusBarHeight; frame.size.height = self.bounds.size.height - frame.origin.y; view.frame = frame; } } } 

再補充一點,看了簡書App適配iOS11發現titleView支持autolayout,這要求titleView必須是可以自撐開的或實現了- intrinsicContentSize方法

- (CGSize)intrinsicContentSize { return UILayoutFittingExpandedSize; } 

繼承自UIScrollView的視圖偏移問題

你們在iOS11設備上運行出現最多問題應該就是tableview莫名奇妙的偏移20pt或者64pt了。。緣由是iOS11棄用了automaticallyAdjustsScrollViewInsets屬性,取而代之的是UIScrollView新增了contentInsetAdjustmentBehavior屬性,這一切的罪魁禍首都是新引入的safeArea,關於safeArea適配這篇文章iOS 11 安全區域適配總結講的很詳細,感興趣的能夠看下,我直接貼適配代碼,由於低版本直接用contentInsetAdjustmentBehavior會報警告,全部定義了以下的宏(感謝@炒雞範的指正,以前的宏犯了個低級錯誤...現改成)

#define adjustsScrollViewInsets(scrollView)\ do {\ _Pragma("clang diagnostic push")\ _Pragma("clang diagnostic ignored \"-Warc-performSelector-leaks\"")\ if ([scrollView respondsToSelector:NSSelectorFromString(@"setContentInsetAdjustmentBehavior:")]) {\ NSMethodSignature *signature = [UIScrollView instanceMethodSignatureForSelector:@selector(setContentInsetAdjustmentBehavior:)];\ NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];\ NSInteger argument = 2;\ invocation.target = scrollView;\ invocation.selector = @selector(setContentInsetAdjustmentBehavior:);\ [invocation setArgument:&argument atIndex:2];\ [invocation retainArguments];\ [invocation invoke];\ }\ _Pragma("clang diagnostic pop")\ } while (0) 

還有的發現某些界面tableViewsectionHeadersectionFooter高度與設置不符的問題,在iOS11中若是不實現 -tableView: viewForHeaderInSection:-tableView: viewForFooterInSection: ,則-tableView: heightForHeaderInSection:- tableView: heightForFooterInSection:不會被調用,致使它們都變成了默認高度,這是由於tableView在iOS11默認使用Self-SizingtableViewestimatedRowHeightestimatedSectionHeaderHeightestimatedSectionFooterHeight三個高度估算屬性由默認的0變成了UITableViewAutomaticDimension,解決辦法簡單粗暴,就是在對應界面實現對應方法或把tableView的這三個屬性設爲0。若是你想全局關閉Self-Sizing可以使用下面這段代碼:

UITableView.appearance.estimatedRowHeight = 0; UITableView.appearance.estimatedSectionFooterHeight = 0; UITableView.appearance.estimatedSectionHeaderHeight = 0; 

若是你使用了Masonry,某些界面須要適配須要適配safeArea,能夠試試下面這段代碼

if (@available(iOS 11.0, *)) { make.edges.equalTo()(self.view.safeAreaInsets) } else { make.edges.equalTo()(self.view) } 

相冊訪問權限

看其餘適配文章上對iOS11相冊權限調整的說明是「iOS11把 NSPhotoLibraryUsageDescription 替換成了NSPhotoLibraryAddUsageDescription」,奇怪的是個人項目並無添加NSPhotoLibraryAddUsageDescription,在訪問相冊時也沒發生crash,後來在仔細閱讀了官方文檔才發現NSPhotoLibraryAddUsageDescription只針對相冊存儲權限,在iOS11上系統默認打開了用戶相冊的訪問權限,若是應用須要存儲權限就須要添加這個key,不然就會crash。

AppIcon

在iOS11上發現了一個奇怪的現象,APP在啓動時圖標會出現黑邊,如圖(處女座實在忍不了...)

 
圖2

緣由是iOS11修改了App啓動動畫,若是你的App圖標有圓角那麼就會變成這個鳥樣了...全部圖標都換成直角就行了,具體規範見 Human Interface Guidelines-App Icon,仍是要聽蘋果爸爸的話啊...

 

iPhoneX

LaunchImage

若是你的APP在iPhoneX上運行發現沒有充滿屏幕,上下有黑色區域,那麼你應該也像我同樣LaunchImage沒有用storyboard而是用的Assets,解決辦法如圖,啓動圖的尺寸爲1125x2436,or you can iOS開發時如何使用 Launch Screen Storyboard

 
圖3

 

TabBarController

若是你使用了原生tabBar,系統會自動適配,由於咱們的項目用了第三方的TabBarController,在iPhoneX運行,tabBar看起來怪怪的(若是不肯定你的項目tabBar在iPhoneX上看起來是否正常,能夠參照模擬器的照片APP,一看便知)...估計做者要等到猴年馬月才適配iPhoneX,項目又着急上線,就本身改了下,主要是tabBar高度及tabBarItem偏移適配,iPhoneX因爲底部安全區的緣由UITabBar高度由49pt變成了83pt,多出來的34pt是空白手勢區域。能夠經過判斷機型來修改相關界面代碼,方式有兩種,經過分辨率判斷:

#define kDevice_Is_iPhoneX ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size) : NO) 

經過設備名稱判斷:
@"iPhone10,1" : @"iPhone 8",
@"iPhone10,4" : @"iPhone 8",
@"iPhone10,2" : @"iPhone 8 Plus",
@"iPhone10,5" : @"iPhone 8 Plus",
@"iPhone10,3" : @"iPhone X",
@"iPhone10,6" : @"iPhone X",
這裏推薦使用UIDeviceIdentifier

目前遇到的就這些坑,歡迎你們指正補充~

做爲一名iOS開發人員,想到當年嘲笑Android開發蛋疼的適配各類機型心情如圖...

 
圖4

後來發現緣由是項目的APP圖標有圓角,由於iOS11修改了啓動動畫,致使這一問題直接暴露了...關於AppIcon規範詳見[ Human Interface Guidelines

 

iOS-App Icon](https://developer.apple.com/ios/human-interface-guidelines/icons-and-images/app-icon/)

WWDC官方視頻:

Updating Your App for iOS 11

Building Apps for iPhone X

Designing for iPhone X


連接:https://www.jianshu.com/p/c355cc4b12c2

============================================= 

xcode9的新功能 

首先是跳轉, 以前按住Command + 左鍵 就能夠跳轉了;然而今天我發現 除了這個: 

Jump to Definition(^⌘):跳轉類頭文件或定義 

Show Quick Help(⌥):顯示幫助文檔 

Edit All in Scope:編輯文檔內全部匹配內容 

在這裏我要說,對於懶得不行的我,簡直要吐,多了一步操做 效率下降不少的好嗎? 

那麼好,你試試 Command + 右鍵 

激不激動,驚不驚喜,意不意外?

再說一下報錯和警告

以前, 錯誤信息只會在錯誤處後面一行顯示,可是錯誤信息過多的時候,在看錯誤信息的時候不免有些不方便,如今好了,當點擊錯誤信息前面的紅點時,錯誤信息會徹底展開,而且有fix功能。

還有一個貼心小功能

就是在點擊一個) ] }等有對應括號的時候,會直接給你找到對應的位置,這對於if嵌套層級關係定位是很是有幫助的說,尤爲是看別人亂七八糟的代碼的時候 ~~~浪裏個浪

關於模擬器

同時能夠打開多個模擬器了,這對於多機型之間的對比和調試有很大的幫助的說 

模擬器尺寸也不是之前的Command + 1 2 3 4 5了 能夠自由調節大小了,方法就像word裏面調整圖片同樣.等比縮放

無線調試 

1.第一次無線調試仍是須要先用數據線鏈接手機,鏈接好以後,選擇Window->Devices and Simulators,或者直接按command+shift+2 

2.進入下一個界面,勾選上connect via network,而後等待它自動鏈接,鏈接成功以後,左上角手機後面會出現一個圖標,表明已經鏈接成功。(成功鏈接的前提是手機跟電腦必須在同一個網段這個很重要) 

三、回到選擇設備的界面,當手機右邊出現那個圖標,說明手機已經準備好,拔掉數據線,能夠直接run項目了

相關文章
相關標籤/搜索