亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

IOS11新特性與兼容適配

2020-07-26 02:37:11
字體:
來源:轉載
供稿:網友

IOS11發布以來,很多新的特性為開發工作提供了方便,小編在此給大家介紹一下IOS11的新特性以及在兼容適配等做的工作。

1. UIView變化

1.1. 更加方便的RTL邊距設置

在之前的系統中我們會使用layoutMargins來獲取和設置控件顯示內容部分的邊緣與控件邊緣的距離。在iOS 11中,新增directionalLayoutMargins屬性來指定邊距。這兩個屬性的結構定義如下:

typedef struct UIEdgeInsets {CGFloat top, left, bottom, right;} UIEdgeInsets;////typedef struct NSDirectionalEdgeInsets {CGFloat top, leading, bottom, trailing; } NSDirectionalEdgeInsets

從結構上看主要是將UIEdgeInsets結構的left和right調整為NSDirectionalEdgeInsets結構的leading和trailing。這一調整主要是為了Right To Left(RTL)語言下可以進行自動適配,例如:要實現文本每行尾部邊距設置為30px,在以前做法則需要判斷語言來區分哪些是RTL語言,然后再做設置,如:

if ([UIView userInterfaceLayoutDirectionForSemanticContentAttribute:self.view.semanticContentAttribute] == UIUserInterfaceLayoutDirectionRightToLeft){// Right to left 語言下每行尾部在左邊self.view.layoutMargins.left = 30;}else{self.view.layoutMargins.right = 30;}

iOS 11 后則可以一步到位,如:

self.view.directionalLayoutMargins = NSDirectionalEdgeInsetsMake(0, 0, 0, 30);

注:測試時需要添加RTL本地化語言才能看到效果

1.2. 安全區域

在iOS 11中新增了安全區域的概念,目的是告訴開發者在這個區域下繪制的內容的顯示才是有效的,否則會存在被遮擋的情況(特別是iPhoneX那帥氣的劉海)。在UIView中新增safeAreaLayoutGuide和safeAreaInsets來獲取屏幕的安全區域(對于frame布局時是很有用的)。如圖所示:

SafeArea示意圖

舉個例子,在一個空白的UIViewController中,分別在viewDidLoad和viewDidAppear方法中輸出view.safeAreaInsets觀察邊距情況,代碼如下:

- (void)viewDidLoad{[super viewDidLoad];NSString *edgeStr = NSStringFromUIEdgeInsets(self.view.safeAreaInsets);NSString *layoutFrmStr = NSStringFromCGRect(self.view.safeAreaLayoutGuide.layoutFrame);NSLog(@"viewDidLoad safeAreaInsets = %@, layoutFrame = %@", edgeStr, layoutFrmStr);=}- (void)viewDidAppear:(BOOL)animated{[super viewDidAppear:animated];NSString *edgeStr = NSStringFromUIEdgeInsets(self.view.safeAreaInsets);NSString *layoutFrmStr = NSStringFromCGRect(self.view.safeAreaLayoutGuide.layoutFrame);NSLog(@"viewDidAppear safeAreaInsets = %@, layoutFrame = %@", edgeStr, layoutFrmStr);}

可以看到其輸出為:

2017-09-19 14:45:50.246095+0800 Sample[5608:1365070] viewDidLoad safeAreaInsets = {0, 0, 0, 0}, layoutFrame = {{0, 0}, {375, 667}}2017-09-19 14:45:50.257807+0800 Sample[5608:1365070] viewDidAppear safeAreaInsets = {20, 0, 0, 0}, layoutFrame = {{0, 20}, {375, 603}}

可見,在視圖顯示完成的時候View的頂部邊距變為了20px,而這20px正是狀態欄的高度。同樣原理,如果你的是一個

UINavigationController那在顯示的時候view.safeAreaInsets就會變成{64, 0, 0, 0}。注意:在該VC下所有的UIView及其子類獲取到safeAreaInsets的值是相同的。

如果你想準確地知道安全區域是什么時候被改變的,可以重寫UIView的safeAreaInsetsDidChange方法,在這個方法里面可以監聽安全區域的邊距調整的事件(如果使用的是UIViewController,其也提供相應方法來實現監聽,下一章節會講述該部分內容),代碼如下:

- (void)safeAreaInsetsDidChange{//寫入變更安全區域后的代碼...}

如果你不想讓safeAreaInsets影響你的視圖布局,則可以將insetsLayoutMarginsFromSafeArea設置為NO,所有的視圖布局將會忽略safeAreaInsets這個屬性了。要注意的是,insetsLayoutMarginsFromSafeArea僅用于AutoLayout,即使該屬性為NO,視圖的safeAreaInsets還是一樣有值,而且安全區域變更方法safeAreaInsetsDidChange一樣被調用。

2. UIViewController變化

2.1. 廢除API

2.1.1. automaticallyAdjustsScrollViewInsets方法

iOS 7中使用該方法來自動調整UIScrollView的contentInset。在iOS 11之后將會使用UIScrollView的

contentInsetAdjustmentBehavior屬性來代替該方法。

2.1.2. topLayoutGuide和bottomLayoutGuide屬性

iOS 7中使用這兩個屬性來指導帶有導航欄(NaviagtionBar)和頁簽欄(TabBar)的視圖排版。其作用如下圖所示

topLayoutGuide & bottomLayoutGuide

在iOS 11之后將使用安全區域(Safe Area)來代替該部分功能的實現。

2.2. 排版

2.2.1. additionalSafeAreaInsets屬性

iOS 11加入安全區域后,對于VC則可以通過該屬性來對該區域附加一個邊距信息。如:

self.additionalSafeAreaInsets = UIEdgeInsetsMake(30, 0, 0, 30);

注意:這里是附加邊距,意思就是在原有的safeAreaInsets值中增加對應的邊距值。如果原來的是{10, 0, 0, 10}, 則最后得出的邊距是{40, 0, 0, 40}。

2.2.2. systemMinimumLayoutMargins和viewRespectsSystemMinimumLayoutMargins屬性

該屬性表示了一個系統最小的邊距信息,所有的視圖排版都應該遵循這個邊距信息的。除非將viewRespectsSystemMinimumLayoutMargins設置為NO。

2.2.3. viewLayoutMarginsDidChange方法

根視圖的邊距變更時會觸發該方法的回調。可以通過該方法來處理當邊距改變時子視圖的布局。

2.2.4. viewSafeAreaInsetsDidChange方法

當視圖的安全區域發生變更時會觸發該方法的回調??梢酝ㄟ^該方法來處理安全區域變更時的子視圖布局。

3. UINavigationBar變化

iOS 11中加入了大標題模式,其顯示效果如下所示:

大標題效果圖

實現該效果需要將導航欄的prefersLargeTitles設置為YES,如:

self.navigationController.navigationBar.prefersLargeTitles = YES;

4. UINavigationItem變化

4.1 控制大標題的顯示

如果你想控制每個視圖的大標題是否顯示,這需要使用UINavigationItem的largeTitleDisplayMode屬性來控制大標題的顯示。該屬性為枚舉類型,定義如下:

typedef NS_ENUM(NSInteger, UINavigationItemLargeTitleDisplayMode){ /// 自動模式,會繼承前一個NavigationItem所設置的模式UINavigationItemLargeTitleDisplayModeAutomatic,/// 當前 Navigationitem 總是啟用大標題模式UINavigationItemLargeTitleDisplayModeAlways,/// 當前 Navigationitem 總是禁用大標題模式UINavigationItemLargeTitleDisplayModeNever,}

根據上面的描述,可以在VC初始化init或者awakeFromNib方法中設置顯示圖標模式:

self.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeAlways;

4.2 控制搜索控制器

iOS 11 中新增了兩個屬性searchController和hidesSearchBarWhenScrolling。這兩個屬性主要用于簡化VC對UISearchController的集成以及視覺優化。其中searchController屬性用于指定當前VC的一個搜索控制器。而hidesSearchBarWhenScrolling屬性則用于控制當視圖滾動時是否隱藏搜索欄的UI,當該值為YES時,搜索欄只有在內容視圖(UIScrollView及其子類)頂部是才會顯示,在滾動過程中會隱藏起來;當該值為NO時,則不受滾動影響一直顯示在導航欄中。具體的代碼實現如下:

- (void)awakeFromNib{[super awakeFromNib];//設置SearchController到navigationItemself.searchController = [[UISearchController alloc] initWithSearchResultsController:self];self.navigationItem.searchController = self.searchController;self.navigationItem.hidesSearchBarWhenScrolling = YES;}

搜索欄隱藏后效果

5. UIScrollView變化

之前的系統中,如果你的滾動視圖包含在一個導航控制器下,系統會自動地調整你的滾動視圖的contentInset。而iOS 11新增adjustedContentInset屬性取替之前contentInset的處理方式。這兩者之間的關系如下圖所示:

adjustedContentInset & contentInset

通過一個例子來驗證這說法,代碼如下:

- (void)viewDidLoad{[super viewDidLoad];NSLog(@"viewDidLoad");NSLog(@"self.tableView.contentInset = %@", NSStringFromUIEdgeInsets(self.tableView.contentInset));NSLog(@"self.tableView.adjustedContentInset = %@", NSStringFromUIEdgeInsets(self.tableView.adjustedContentInset));}- (void)viewDidAppear:(BOOL)animated{[super viewDidAppear:animated];NSLog(@"viewDidAppear");NSLog(@"self.tableView.contentInset = %@", NSStringFromUIEdgeInsets(self.tableView.contentInset));NSLog(@"self.tableView.adjustedContentInset = %@", NSStringFromUIEdgeInsets(self.tableView.adjustedContentInset));}

執行后輸出下面信息:

2017-09-20 11:54:09.361348+0800 Sample[1276:375286] viewDidLoad2017-09-20 11:54:09.361432+0800 Sample[1276:375286] self.tableView.contentInset = {0, 0, 0, 0}2017-09-20 11:54:09.361462+0800 Sample[1276:375286] self.tableView.adjustedContentInset = {0, 0, 0, 0}2017-09-20 11:54:09.420000+0800 Sample[1276:375286] viewDidAppear2017-09-20 11:54:09.420378+0800 Sample[1276:375286] self.tableView.contentInset = {0, 0, 0, 0}2017-09-20 11:54:09.420554+0800 Sample[1276:375286] self.tableView.adjustedContentInset = {20, 0, 0, 0}

可見,tableView的adjustedContentInset自動改變了,但是contentInset的值是保持不變的。注:一定要是VC的根視圖為UIScrollView或者其子類才能夠得到adjustedContentInset的值,否則獲取到的是空值。而且非根視圖的滾動視圖就會被安全區域所裁剪,看到的樣式如下圖所示:

樣式效果對比

通過使用contentInsetAdjustmentBehavior屬性可以控制 adjustedContentInset的變化。該屬性為枚舉類型,其定義如下:

typedef NS_ENUM(NSInteger, UIScrollViewContentInsetAdjustmentBehavior) {UIScrollViewContentInsetAdjustmentAutomatic,UIScrollViewContentInsetAdjustmentScrollableAxes, UIScrollViewContentInsetAdjustmentNever,UIScrollViewContentInsetAdjustmentAlways, }

其中UIScrollViewContentInsetAdjustmentAutomatic與UIScrollViewContentInsetAdjustmentScrollableAxes一樣,ScrollView會自動計算和適應頂部和底部的內邊距并且在scrollView 不可滾動時,也會設置內邊距;

UIScrollViewContentInsetAdjustmentNever表示不計算內邊距;UIScrollViewContentInsetAdjustmentAlways則根據視圖的安全區域來計算內邊距。

如果需要感知adjustedContentInset的變化,然后根據變化進行不同操作則可以通過重寫新增的adjustedContentInsetDidChange方法或者實現UIScrollViewDelegate中的scrollViewDidChangeAdjustedContentInset方法來實現。如:

//重寫方法- (void)adjustedContentInsetDidChange{[super adjustedContentInsetDidChange];//執行操作...}//實現委托- (void)scrollViewDidChangeAdjustedContentInset:(UIScrollView *)scrollView{//執行操作...}

除了新增上述所說的邊距相關屬性外,還新增了contentLayoutGuide和frameLayoutGuide屬性,用于描述內容布局和整體布局信息。

6. UI主線程操作日志提醒

之前的系統中如果你不小心將UI放入非主線程操作時,Debug日志是沒有任何信息反饋的,導致有時候在排錯時非常困難。在新的Xcode 9中,如果你處于調試狀態,將UI放入非主線程操作,如:

dispatch_async(dispatch_get_global_queue(0, 0), ^{self.tv = [[UITableView alloc] initWithFrame:self.view.bounds];[self.view addSubview:self.tv];NSLog(@"self.tv.adjustedContentInset = %@", NSStringFromUIEdgeInsets(self.tv.adjustedContentInset));});

Log中會出現下面提示:

=================================================================Main Thread Checker: UI API called on a background thread: -[UIView bounds]PID: 16919, TID: 2972321, Thread name: (none), Queue name: com.apple.root.default-qos, QoS: 21Backtrace:4 Sample    0x00000001004885dc __29-[ViewController viewDidLoad]_block_invoke + 1125 libdispatch.dylib   0x000000010077149c _dispatch_call_block_and_release + 246 libdispatch.dylib   0x000000010077145c _dispatch_client_callout + 167 libdispatch.dylib   0x000000010077d56c _dispatch_queue_override_invoke + 9808 libdispatch.dylib   0x0000000100782b54 _dispatch_root_queue_drain + 6169 libdispatch.dylib   0x0000000100782880 _dispatch_worker_thread3 + 13610 libsystem_pthread.dylib  0x000000018300b130 _pthread_wqthread + 126811 libsystem_pthread.dylib  0x000000018300ac30 start_wqthread + 4

從日志中了解到一個Main Thread Checker的東西,根據蘋果官方文檔來看他是作用在AppKit(OSX中)、UIKit還有一些相關API上的后臺線程,主要是用來監控這些框架中的接口是否在主線程中進行調用,如果沒有則發出警告日志。因此,利用這個功能可以讓我們快速地定位那些地方存在問題。

以上就是本次IOS11新特性與兼容適配介紹的全部內容,如果大家還有任何問題可以在下方留言處留言討論。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产一区二区三区日韩欧美| 欧美日韩中文字幕在线视频| 欧美性生交大片免费| 日韩欧美福利视频| 久久这里只有精品99| 国产精品久久9| 成人国产精品一区二区| 97免费视频在线播放| 欧美有码在线视频| 亚洲国产精品久久久久| 久久久999精品视频| 国产一区二区在线播放| 4k岛国日韩精品**专区| 久久久久国产精品一区| 亚洲精品99久久久久中文字幕| 一本一本久久a久久精品牛牛影视| 国产精品一区二区三区久久久| 高清日韩电视剧大全免费播放在线观看| 久久久精品免费视频| 久久亚洲精品中文字幕冲田杏梨| 性欧美xxxx视频在线观看| 91影院在线免费观看视频| 成人动漫网站在线观看| 最近免费中文字幕视频2019| 最近日韩中文字幕中文| 91国在线精品国内播放| 亚洲字幕在线观看| 黄色成人av网| 亚洲黄页网在线观看| 国产一区二区三区在线观看视频| 亚洲成人久久电影| 亚洲精品日韩av| www.亚洲成人| 国产成人精品一区二区三区| 日韩精品在线观看网站| 国产一区二区激情| www高清在线视频日韩欧美| 91精品视频在线免费观看| 亚洲一区二区三区四区在线播放| 亚洲夜晚福利在线观看| 国产成人综合精品| 日韩久久午夜影院| 久久精品国产久精国产一老狼| 精品国产一区二区三区在线观看| 色伦专区97中文字幕| 国产成人av在线| 欧美一级高清免费| 成人网址在线观看| 国产成人精品视频在线观看| 亚洲女人被黑人巨大进入al| 日本成人在线视频网址| 欧美日韩国产丝袜另类| 亚洲国产另类 国产精品国产免费| 欧美性xxxx| 欧洲中文字幕国产精品| 亚洲 日韩 国产第一| 91国自产精品中文字幕亚洲| 日韩电影在线观看永久视频免费网站| 欧美黑人巨大xxx极品| 91爱视频在线| 91精品视频专区| 日韩**中文字幕毛片| 欧美乱大交xxxxx另类电影| 欧美精品在线免费播放| 黑人与娇小精品av专区| 久久久精品日本| 国产欧美一区二区白浆黑人| 国产精自产拍久久久久久| 久久亚洲精品中文字幕冲田杏梨| 日本在线观看天堂男亚洲| 亚洲国产91精品在线观看| 九九精品在线观看| 久久亚洲精品网站| 久久久久久久久综合| 欧美精品一区在线播放| 国产精品久久中文| 欧美精品在线免费观看| 亚洲欧美日韩爽爽影院| 欧美成人一区在线| 国产精品揄拍500视频| 亚洲黄色成人网| 欧美午夜xxx| 亚洲午夜精品久久久久久久久久久久| 亚洲成人久久网| 不卡av日日日| 欧美多人乱p欧美4p久久| 精品久久久精品| 欧美日韩亚洲激情| 欧美在线观看一区二区三区| 亚洲综合精品伊人久久| 日韩精品视频免费专区在线播放| 国产成人综合一区二区三区| 久久久国产精品免费| 久久福利网址导航| 精品国产成人av| 亚洲自拍偷拍第一页| 国产精品免费看久久久香蕉| 爱福利视频一区| 日韩大片在线观看视频| 亚洲第一区第二区| 亚洲美女又黄又爽在线观看| 九九热r在线视频精品| 久久精品成人欧美大片古装| 伊人久久久久久久久久久久久| 日韩中文字幕在线| 欧美日韩性生活视频| 欧美日韩成人免费| 韩曰欧美视频免费观看| 国产中文欧美精品| 成人中文字幕+乱码+中文字幕| 国产精品欧美日韩一区二区| 91亚洲精品久久久久久久久久久久| 久久久国产精品视频| 国产精品一区二区三| 久久国产精品免费视频| 久久国产精品久久国产精品| 国产精品91一区| 日韩av网站大全| 欧美在线观看日本一区| 91精品国产高清久久久久久久久| 国产精品亚洲自拍| 亚洲一区二区三区视频播放| 亚洲国产天堂久久国产91| 亚洲天堂成人在线视频| 精品久久久久久久久久久久| 欧美孕妇与黑人孕交| 亚洲国产精品久久| 国产精品日韩专区| 日韩精品视频在线观看网址| 免费av在线一区| 精品国产一区二区三区在线观看| 这里只有精品丝袜| 成人免费看片视频| 欧美午夜片欧美片在线观看| 欧美激情一区二区三级高清视频| 久久久久久久电影一区| 亚洲片国产一区一级在线观看| 成人久久一区二区三区| 亚洲欧洲一区二区三区久久| 九九九热精品免费视频观看网站| 亚洲www在线| 日韩精品欧美激情| 日韩欧美国产黄色| 精品美女永久免费视频| 亚洲国产欧美久久| 亚洲天堂视频在线观看| 国产精品视频白浆免费视频| 亚洲影院在线看| 欧美精品免费播放| 欧美性xxxx极品hd满灌| 午夜精品蜜臀一区二区三区免费| 国产欧美va欧美va香蕉在线| 欧美专区日韩视频| 最近更新的2019中文字幕| 日韩欧美成人免费视频| 国产精品欧美一区二区| 欧美精品成人在线| 国产美女搞久久| 国产成人91久久精品| 欧美一区二区三区免费观看| 在线视频国产日韩| 国产亚洲欧洲在线| 伊人伊人伊人久久| 国产精品视频午夜|