亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

關(guān)于iOS 11的一些新特性適配實(shí)踐總結(jié)

 更新時(shí)間:2017年11月07日 10:29:42   作者:丁同舟、王博文  
iOS 11 為整個(gè)生態(tài)系統(tǒng)的 UI 元素帶來了一種更加大膽、動(dòng)態(tài)的新風(fēng)格。下面這篇文章主要給大家總結(jié)介紹了關(guān)于iOS 11的一些新特性適配實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。

前言

iOS 11 已經(jīng)發(fā)布了一段時(shí)間了,隨手記團(tuán)隊(duì)也早早的完成了適配。在這里,我們做了點(diǎn)總結(jié),與大家一起分享一下關(guān)于 iOS 11 一些新特性的適配。

UIView & UIViewController

Layout Margins

iOS 11 中,官方提供了一種新的布局方法——通過 layout margins 進(jìn)行布局。官方文檔 Positioning Content Within Layout Margins 稱,使用這種布局可以保證各個(gè) content 之間不會(huì)相互覆蓋。

總的來說,layout margins 可以視作視圖的內(nèi)容和內(nèi)容之間的空隙。它由每個(gè)邊的 insetValues 組成,分別是 top, bottom, leading and trailing. 對(duì)應(yīng)的是上、下、左、右。

Auto Layout with Layout Margins

如果使用 Auto Layout 進(jìn)行布局,并希望約束遵循 layout margins,那么必須要在 Xcode 中打開 Constrain to margins 選項(xiàng)。這樣,如果父視圖的 layout margins 改變,那么所有綁定于父視圖 margins 的子視圖都會(huì)更新布局。

注意

如果沒有開啟這個(gè)選項(xiàng),那么所有建立的約束都會(huì)依賴于父視圖的 bounds.

Manually Layout with Layout Margins

如果沒有使用 Auto Layout, 而是通過設(shè)置 frame 布局的話,要遵循 layout margins 也并不困難,只需要在布局計(jì)算時(shí)使用 directionalLayoutMargins 這個(gè)屬性。

var directionalLayoutMargins: NSDirectionalEdgeInsets { get set }

官方文檔中闡述道,對(duì)于 view controller 的根視圖,它的 directionalLayoutMargins 默認(rèn)值是由 systemMinimumLayoutMargins和SafeAreaInsets 決定的。在 iPhone X 下打印根視圖的這三個(gè)屬性可以看到它們的關(guān)系。

override func viewDidAppear(_ animated: Bool) {
 super.viewDidAppear(animated)
 print("SafeAreaInsets :" + "\(self.view.safeAreaInsets)")
 print("systemMinimumLayoutMargins :" + "\(self.systemMinimumLayoutMargins)")
 print("directionalLayoutMargins: " + "\(self.view.directionalLayoutMargins)")
 
 // SafeAreaInsets :UIEdgeInsets(top: 88.0, left: 0.0, bottom: 34.0, right: 0.0)
 // systemMinimumLayoutMargins :NSDirectionalEdgeInsets(top: 0.0, leading: 16.0, bottom: 0.0, trailing: 16.0)
 // directionalLayoutMargins: NSDirectionalEdgeInsets(top: 88.0, leading: 16.0, bottom: 34.0, trailing: 16.0)
}

結(jié)果顯而易見,directionalLayoutMargins 的默認(rèn)值由 systemMinimumLayoutMargins 和 safeAreaInsets 組成。

注意

systemMinimumLayoutMargins 屬性是否可用由 view controller 的布爾值屬性viewRespectsSystemMinimumLayoutMargins決定,默認(rèn)為true.

如果手動(dòng)對(duì) directionalLayoutMargins 賦值,那么在 viewRespectsSystemMinimumLayoutMargins 開啟的情況下,系統(tǒng)會(huì)比較賦值后的 directionalLayoutMargins 和 systemMinimumLayoutMargins ,并取其較大值作為最終的 margins。

print("systemMinimumLayoutMargins :" + "\(self.systemMinimumLayoutMargins)")
print("origin directionalLayoutMargins: " + "\(self.view.directionalLayoutMargins)")

// 這里把 leading 和 trailing 分別賦值為相對(duì)于 systemMinimumLayoutMargins 的較大值20和較小值10
self.view.directionalLayoutMargins = NSDirectionalEdgeInsets(top: 0, leading: 20, bottom: 0, trailing: 10)
print("assigned directionalLayoutMargins: " + "\(self.view.directionalLayoutMargins)")

// 打印日志可見只有 leading 的值改變?yōu)槭謩?dòng)賦的值,trailing 依然遵循于 systemMinimumLayoutMargins
systemMinimumLayoutMargins :NSDirectionalEdgeInsets(top: 0.0, leading: 16.0, bottom: 0.0, trailing: 16.0)
origin directionalLayoutMargins: NSDirectionalEdgeInsets(top: 88.0, leading: 16.0, bottom: 34.0, trailing: 16.0)
assigned directionalLayoutMargins: NSDirectionalEdgeInsets(top: 88.0, leading: 20.0, bottom: 34.0, trailing: 16.0)

注意

如果不希望受到systemMinimumLayoutMargins的影響,那么把 view controller 的viewRespectsSystemMinimumLayoutMargins設(shè)為false即可.

Navigation bar

進(jìn)入了 iOS 11,蘋果為提供了更為漂亮和醒目的大標(biāo)題的樣式,如果想開啟這樣的功能,其實(shí)很簡(jiǎn)單。
只需要將 navigation bar 中的 prefersLargeTitles 置為 true 即可,這樣便自動(dòng)有了來自 iOS 11 中的大標(biāo)題的樣式。

self.navigationController.navigationBar.prefersLargeTitles = true

這里可以注意到,prefersLargeTitles 是配置在的 navigation controller 中的 navigation bar 中的。也就是說該 navigation controller 容器中的所有的 view controller 在此配置之后,都會(huì)受到影響。所以如果你要在當(dāng)前的 navigation controller 中推入一個(gè)新的 view controller 的話,那么該 view controller 也會(huì)是大標(biāo)題。因此為了避免這個(gè)問題,UIKit 為 UINavigationItem 提供了 largeTitleDisplayMode 屬性。

該屬性默認(rèn)為 UINavigationItem.LargeTitleDisplayMode.automatic, 即保持與前面已經(jīng)顯示過的 navigation item 一致的樣式。 如果想在后來的一個(gè) view controller 避免大標(biāo)題樣式那么可以這么配置:

self.navigationItem.largeTitleDisplayMode = .never

除了大標(biāo)題以外,在 iOS 11 中,UIKit 還為 navigation item 提供了便于管理搜索的接口。
具體參考如下:

self.navigationItem.searchController = self.searchController
self.navigationItem.hidesSearchBarWhenScrolling = true

在配置好你的 search controller 之后便可以直接提供給 navigation item 的 searchController屬性上,這樣的便能夠在導(dǎo)航欄看到一個(gè)漂亮的搜索框了。

此外還可以給 navigation item 中的屬性 hidesSearchBarWhenScrolling 設(shè)置為 true, 他可以使你 view controller 中管理的 scroll view 在滑動(dòng)的時(shí)候自動(dòng)隱藏 search bar.

Scroll view

如果使用過 view controller 管理過 scroll view 的話,想必對(duì) automaticallyAdjustsScrollViewInsets 這個(gè)屬性一定不陌生。在 iOS 11 之前,該屬性可以讓 view controller 自動(dòng)管理 scroll view 中的 content inset. 但是,在實(shí)際在開發(fā)的過程中,這樣的自動(dòng)管理的方式會(huì)帶來麻煩,尤其是一些在 content inset 需要?jiǎng)討B(tài)調(diào)整的情況。

為此,在 iOS 11, UIKit 廢棄了 automaticallyAdjustsScrollViewInsets 屬性,并將該的職責(zé)轉(zhuǎn)移到 scroll view 本身。因此,在 iOS 11 中,為了解決這個(gè)問題,有兩個(gè) scroll view 的新屬性。一個(gè)是用于管理調(diào)整 content inset 行為的屬性 contentInsetAdjustmentBehavior, 另一個(gè)是獲取調(diào)整后的填充的屬性 adjustedContentInset. 同時(shí),UIScrollViewDelegate 也提供了新的代理方法,以方便開發(fā)者獲取 inset 變化的時(shí)機(jī):

optional func scrollViewDidChangeAdjustedContentInset(_ scrollView: UIScrollView)

至此,對(duì)于這個(gè)「自動(dòng)為開發(fā)者設(shè)置 inset」 的特性,蘋果算是提供了相當(dāng)完備的接口了。

不過作為開發(fā)者的我們要注意的是,如果對(duì)原本自動(dòng)設(shè)置 contentInset 屬性的行為有依賴,在新的 iOS 11 的適配中,可能得做出調(diào)整。

此外,為了便于開發(fā)者在 scroll view 中使用 Auto Layout. UIKit 還提供了兩個(gè)新的屬性。一個(gè)是 contentLayoutGuide, 它用來獲取當(dāng)前在 scroll view 內(nèi)的內(nèi)容的 layout guides. 而另一個(gè)是 frameLayoutGuide, 他用來獲取實(shí)際內(nèi)容的 layout guides. 這樣說有點(diǎn)繁瑣,還是看 WWDC 的原圖吧:

Table view

實(shí)際上對(duì)于 table view 而言,其最大的更新就在于新的特性 Drag and Drop 了吧。但是這個(gè)特性在適配中暫時(shí)不需要考慮,本文就不介紹了,讓我們一起來看看其他有意思的變化。

首先是在 iOS 11 中,table view 默認(rèn)開啟了 self-sizing, 可以注意到 estimatedRowHeight, estimatedSectionHeaderHeight 以及 estimatedSectionFooterHeight 都被默認(rèn)設(shè)置為 UITableViewAutomaticDimension. 但是我們知道,如果原本已經(jīng)實(shí)現(xiàn) tableView:heightForRowAtIndexPath: 之類的方法并返回了高度,那么在布局方面是不會(huì)有影響的,這對(duì) iOS 11 適配而言是個(gè)好消息。

在 iOS 11 中,有了新的 layout margins 的概念,因此 UIKit 也為 separator inset 做了額外的補(bǔ)充?,F(xiàn)在 separator inset 可以有兩個(gè)來源,一個(gè)是從 cell 的邊緣開始 (UITableViewSeparatorInsetReference.fromCellEdges) ,另一個(gè)是從 table view 默認(rèn)的填充開始 (UITableViewSeparatorInsetReference.fromAutomaticInsets)。其中,默認(rèn)的填充由 table view 的 layout margins 進(jìn)行控制。

此外,iOS 11 還為 table view 添加了更多的滑動(dòng)操作的控制能力。分別可以通過以下兩個(gè) UITableViewDelegate 的方法

實(shí)現(xiàn):

func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?

我們可以注意到兩個(gè)方法均要求返回一個(gè) UISwipeActionsConfiguration 實(shí)例。為構(gòu)造這個(gè)實(shí)例,我們還需要構(gòu)造一個(gè)由 UIContextualAction 實(shí)例組成的數(shù)組。UIContextualAction 與原本的 UITableViewRowAction 大致類似,但是要注意在 contextual action 的參數(shù) handler 中,我們需要調(diào)用 handler 參數(shù)中的 completionHandler 才能完成操作。從這一點(diǎn)我們可以看到,似乎在新的 action 中,我們可以做一些異步操作相關(guān)的事情。

下面是一個(gè)刪除操作的示例:

override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
 let contextualAction = UIContextualAction.init(style: .destructive, title: "Delete") { (style, title, completionHandler) in
  // 刪除指定的數(shù)據(jù)
  completionHandler(true)
 }
 
 let actionsConfiguration = UISwipeActionsConfiguration.init(actions: [contextualAction])
 return actionsConfiguration
}

在 swipe actions configuration 中,我們還需要注意一點(diǎn),那就是新的 performsFirstActionWithFullSwipe 屬性。通過開啟這個(gè)屬性的配置(默認(rèn)開啟),我們可以為第一個(gè)動(dòng)作提供 full swipe 操作 (一種通過過度滑動(dòng)從而觸發(fā)動(dòng)作的交互) 。

如果僅僅實(shí)現(xiàn)了以往的編輯的代理方法,在 iOS 11 中,對(duì)于第一個(gè)動(dòng)作將會(huì)默認(rèn)支持 full swipe, 且不能關(guān)閉。

Face ID

如果已經(jīng)做過了 Touch ID 那么實(shí)際上適配 Face ID 便并不難了。即便是不做任何的改動(dòng),估計(jì) Face ID 也是可以直接使用的(寫作時(shí), iPhone X 還未上市),當(dāng)然相關(guān)的體驗(yàn)肯定會(huì)打點(diǎn)折扣,畢竟文案以及相關(guān)的提示操作還是在僅有 Touch ID 的前提下實(shí)現(xiàn)的。

與以往一樣,可以通過 LAContext 類實(shí)現(xiàn)生物識(shí)別認(rèn)證。不過需要注意的是,因?yàn)橹С至诵碌?Face ID 認(rèn)證,蘋果便為 LAContext 類添加了新的接口 biometryType 用于區(qū)分 Touch ID 以及 Face ID。同時(shí),以往僅涵蓋 Touch ID 的錯(cuò)誤類型,也在 iOS 11 中廢棄了,相應(yīng)的,蘋果提供了新的更通用的錯(cuò)誤類型予以替代。

IOS 11 下適配UITableView

UIScrollView及其子類在IOS 11之前的版本UI顯示完全正常,但是在IOS 11上面會(huì)顯示奇葩的界面。

 (1)先看一下UITablevIew。

原本在VC里面的automaticallyAdjustsScrollViewInsets竟然過期了,在IOS 11下 APPLE推薦使用UIScrollView的contentInsetAdjustmentBehavior屬性進(jìn)行設(shè)置自動(dòng)計(jì)算滾動(dòng)視圖的內(nèi)容邊距。

@property(nonatomic,assign) BOOL automaticallyAdjustsScrollViewInsets

在IOS11的SDK下,UIScrollView的這個(gè)屬性

@property(nonatomic) UIScrollViewContentInsetAdjustmentBehavior contentInsetAdjustmentBehavior //這個(gè)屬性是一個(gè)枚舉類型的

{

UIScrollViewContentInsetAdjustmentAutomatic,//scrollView會(huì)自動(dòng)計(jì)算和適應(yīng)頂部和底部的內(nèi)邊距并且在scrollView 不可滾動(dòng)時(shí),也會(huì)設(shè)置內(nèi)邊距.

UIScrollViewContentInsetAdjustmentScrollableAxes, //自動(dòng)適應(yīng)邊距

UIScrollViewContentInsetAdjustmentNever, //和 automaticallyAdjustsScrollViewInsets=NO有著同樣的效果,不計(jì)算內(nèi)邊距

UIScrollViewContentInsetAdjustmentAlways//根據(jù)safeAreaInsets (安全區(qū)域)計(jì)算內(nèi)邊距

 }

所以,在IOS 11 下,需要設(shè)置ScrollView:

 self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;

如果需要全局設(shè)置的話,需要這么設(shè)置:

if (@available(iOS 11.0, *)) {

 

 [[UIScrollView appearance] setContentInsetAdjustmentBehavior:UIScrollViewContentInsetAdjustmentNever];

}

這樣設(shè)置后使用UITableview 、UICollectionView、UIScrollview的時(shí)候就不需要再單獨(dú)設(shè)置該屬性了,因?yàn)閁IView以及他的子類都是遵循UIAppearance協(xié)議的。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

Reference

  • Positioning Content Within Layout Margins
  • directionalLayoutMargins
  • systemMinimumLayoutMargins
  • SafeAreaInsets

相關(guān)文章

  • iOS App項(xiàng)目中引入SQLite數(shù)據(jù)庫的教程

    iOS App項(xiàng)目中引入SQLite數(shù)據(jù)庫的教程

    SQLite是一個(gè)極輕的嵌入式數(shù)據(jù)庫,在應(yīng)用程序中捆綁使用可以更方便地幫助操控關(guān)系型數(shù)據(jù),這里我們就來看一下iOS App項(xiàng)目中引入SQLite數(shù)據(jù)庫的教程
    2016-06-06
  • iOS中UILabel設(shè)置居上對(duì)齊、居中對(duì)齊、居下對(duì)齊及文字置頂顯示

    iOS中UILabel設(shè)置居上對(duì)齊、居中對(duì)齊、居下對(duì)齊及文字置頂顯示

    這篇文章主要給大家介紹了關(guān)于iOS中UILabel如何設(shè)置居上對(duì)齊、居中對(duì)齊、居下對(duì)齊及文字置頂顯示效果的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-12-12
  • iOS設(shè)置可選擇圓角方向的控件圓角

    iOS設(shè)置可選擇圓角方向的控件圓角

    在iOS開發(fā)中會(huì)遇到設(shè)置控件圓角的效果,這篇文章就給大家分享了實(shí)現(xiàn)的方法,且可以選擇圓角的方向,有需要的朋友們可以參考借鑒,下面來一起學(xué)習(xí)學(xué)習(xí)吧。
    2016-11-11
  • IOS實(shí)現(xiàn)郵箱模糊匹配的功能

    IOS實(shí)現(xiàn)郵箱模糊匹配的功能

    在一些App的訂單填寫頁,輸入用戶郵箱有個(gè)提示郵箱后綴的功能,很好用!還可以根據(jù)各個(gè)郵箱類型用戶量來做一個(gè)優(yōu)先級(jí)的匹配哦。這個(gè)功能該如何實(shí)現(xiàn)呢,下面來一起看看。
    2016-08-08
  • iOS 監(jiān)聽回調(diào)機(jī)制KVO實(shí)例

    iOS 監(jiān)聽回調(diào)機(jī)制KVO實(shí)例

    下面小編就為大家分享一篇iOS 監(jiān)聽回調(diào)機(jī)制KVO實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • iOS實(shí)現(xiàn)雙向滑動(dòng)條效果

    iOS實(shí)現(xiàn)雙向滑動(dòng)條效果

    這篇文章主要為大家詳細(xì)介紹了iOS實(shí)現(xiàn)雙向滑動(dòng)條效果的相關(guān)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-03-03
  • iOS 使用AFN上傳視頻到服務(wù)器示例代碼

    iOS 使用AFN上傳視頻到服務(wù)器示例代碼

    本篇文章主要介紹了iOS 使用AFN上傳視頻到服務(wù)器示例代碼,具有一定的參考價(jià)值,有興趣的可以了解一下。
    2017-04-04
  • 詳解iOS webview加載時(shí)序和緩存問題總結(jié)

    詳解iOS webview加載時(shí)序和緩存問題總結(jié)

    本篇文章主要介紹了iOS webview加載時(shí)序和緩存問題總結(jié) ,這兩天學(xué)習(xí)了Vue.js 感覺組件這個(gè)地方知識(shí)點(diǎn)挺多的,而且很重要,所以,今天添加一點(diǎn)小筆記。
    2017-09-09
  • iOS圖片放大的方式(transform和frame)

    iOS圖片放大的方式(transform和frame)

    這篇文章主要介紹了iOS圖片放大的兩種方式,transform方式放大圖片,從中心開始放大,另一種用frame改變寬高,詳細(xì)內(nèi)容請(qǐng)參考下文
    2016-04-04
  • iOS NSThread和NSOperation的基本使用詳解

    iOS NSThread和NSOperation的基本使用詳解

    下面小編就為大家分享一篇iOS NSThread和NSOperation的基本使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01

最新評(píng)論