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

首頁 > 系統 > iOS > 正文

IOS11新特性與兼容適配

2019-10-21 18:43:41
字體:
來源:轉載
供稿:網友

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布局時是很有用的)。如圖所示:

IOS11,新特性,兼容,適配

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)的視圖排版。其作用如下圖所示

IOS11,新特性,兼容,適配

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中加入了大標題模式,其顯示效果如下所示:

IOS11,新特性,兼容,適配

大標題效果圖

實現該效果需要將導航欄的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;}

IOS11,新特性,兼容,適配

IOS11,新特性,兼容,適配

搜索欄隱藏后效果

5. UIScrollView變化

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

IOS11,新特性,兼容,適配

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的值,否則獲取到的是空值。而且非根視圖的滾動視圖就會被安全區域所裁剪,看到的樣式如下圖所示:

IOS11,新特性,兼容,適配

樣式效果對比

通過使用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新特性與兼容適配介紹的全部內容,如果大家還有任何問題可以在下方留言處留言討論。


注:相關教程知識閱讀請移步到IOS開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产成人精品在线观看| 国产精品日韩在线一区| 精品国产999| 精品性高朝久久久久久久| 亚洲第一网站男人都懂| 国产精品午夜视频| 日韩精品中文字| 国产视频999| 亚洲国产高清高潮精品美女| 亚洲精品视频播放| 欧美诱惑福利视频| 69精品小视频| 国产一区二区三区久久精品| 色悠悠国产精品| 精品国产一区二区三区久久狼5月| 亚洲成人在线视频播放| 午夜精品久久久久久久男人的天堂| 色狠狠久久aa北条麻妃| 日韩av大片在线| 国产视频丨精品|在线观看| 国产精品色婷婷视频| 日韩国产激情在线| 68精品久久久久久欧美| www.亚洲成人| 精品一区二区三区四区在线| 国产精品视频大全| 国产精品91在线观看| 国产亚洲精品91在线| 一本一道久久a久久精品逆3p| 欧美在线精品免播放器视频| 国产精品直播网红| 一个人看的www欧美| 久久精品在线播放| 久久久久久91香蕉国产| 性欧美xxxx视频在线观看| 91视频免费网站| 97视频在线观看免费高清完整版在线观看| 成人免费看黄网站| 91香蕉国产在线观看| 亚洲福利视频网| 亚洲国产精品嫩草影院久久| 亚州av一区二区| 狠狠色狠狠色综合日日五| 亚洲天堂日韩电影| 久久久久久这里只有精品| 激情成人在线视频| 亚洲精选在线观看| 亚洲精品成a人在线观看| 欧美性生交大片免费| 欧美最猛性xxxxx免费| 久久精品2019中文字幕| 亚洲一区二区自拍| 国产原创欧美精品| 精品国产一区二区三区四区在线观看| 亚洲人成电影在线播放| 8x拔播拔播x8国产精品| 亚洲精品一区二区三区不| 日韩欧美精品中文字幕| 欧美一级视频在线观看| 久久久亚洲精品视频| 久久久欧美精品| 日韩大片在线观看视频| 97国产在线视频| 国产精品欧美风情| 欧美日韩亚洲高清| 国产精品久久久久77777| 亚洲一区二区久久久久久久| 日韩精品视频在线免费观看| 欧美激情影音先锋| 国产三级精品网站| 国产欧美最新羞羞视频在线观看| 日韩成人av在线| 97精品免费视频| 亚洲女人被黑人巨大进入al| 久久久久久久久久av| 国产啪精品视频| 亚洲国内精品在线| 亚洲视频网站在线观看| 亚洲午夜未删减在线观看| www.日韩不卡电影av| 欧美激情三级免费| 国产精品96久久久久久| 亚洲人成网站777色婷婷| 77777亚洲午夜久久多人| 精品在线欧美视频| 亚洲色在线视频| 亚洲电影免费观看高清完整版在线观看| 色老头一区二区三区在线观看| 久久精品视频亚洲| 国产成人精品在线播放| 日韩av在线一区二区| 韩国美女主播一区| 日韩精品亚洲精品| 午夜精品美女自拍福到在线| 亚洲成人激情图| 亚洲综合在线中文字幕| 亚洲一区二区在线| 国产精自产拍久久久久久蜜| 亚洲视频精品在线| 91经典在线视频| 超在线视频97| 欧美成人合集magnet| 欧美丰满少妇xxxxx做受| 久久久久久97| 911国产网站尤物在线观看| 中文在线不卡视频| 日韩电影中文字幕一区| 亚洲第一二三四五区| 欧美电影第一页| 7m第一福利500精品视频| 国产精品福利网| 精品久久久久久中文字幕大豆网| 亚洲精品www久久久| 色综合亚洲精品激情狠狠| 日本伊人精品一区二区三区介绍| 久久精品视频中文字幕| 国产精品久久久久久久久久三级| 神马久久桃色视频| 午夜精品久久久久久久久久久久| 欧美裸体视频网站| 欧美精品一区二区三区国产精品| 91久久嫩草影院一区二区| 中文字幕一精品亚洲无线一区| 亚洲欧洲激情在线| 国产精品午夜视频| 国产成人激情视频| 91亚洲精品久久久| 欧美理论电影在线观看| 欧美日韩人人澡狠狠躁视频| 俺去了亚洲欧美日韩| 日韩欧美在线观看| 欧美亚洲视频一区二区| 欧美一级片久久久久久久| 成人免费视频在线观看超级碰| 国产成人在线亚洲欧美| 成人黄色激情网| 麻豆国产精品va在线观看不卡| 国产va免费精品高清在线观看| 久久久久久久久国产| 国产999视频| 久久精品久久精品亚洲人| 亚洲成人精品久久| 日韩av在线精品| 日本久久久久久久久| 国产欧美一区二区三区久久| 久久久国产精品x99av| 精品国产区一区二区三区在线观看| 欧美成人激情图片网| 亚洲人成在线观看| 亚洲sss综合天堂久久| 日韩在线国产精品| 亚洲欧美日本另类| 日本欧美一二三区| 91豆花精品一区| 国产欧亚日韩视频| 久久精视频免费在线久久完整在线看| 在线精品视频视频中文字幕| 黑人与娇小精品av专区| 91久久精品国产91久久性色| 日韩精品视频中文在线观看| 一本色道久久综合狠狠躁篇怎么玩| 热99精品只有里视频精品| 欧美视频国产精品| 国产精品国内视频|