WeTest 導讀ios
前幾天發如今作的APP在iOS11系統上動畫有異常,在其餘系統的設備上都是正常的,動畫的操做是觀察tableView的contentOffset變化後執行的,異常動畫發生在tableView reloadData以後,也就是說tableView reloadData以後,tableView的contentOffset發生了幾回變化。查了下資料發現緣由是iOS11中默認開啓了Self-Sizing,在WWDC 2017 session204 Updating Your App for iOS 11 中有介紹,所以研究了下這個session,本文做爲一個總結,下文的第三部分會有對上述的動畫異常的緣由分析及解決方式。數組
本文內容包括:集成了搜索的大標題欄、橫向選項卡欄、Margins 和 Insets以及 UIScrollView和UITableView 的更新和功能更強大的滑動操做。緩存
1、在UIKit’s Bars中加入的新功能安全
WWDC經過iOS新增的文件管理App:Files開始介紹,在Files這個APP中可以看到iOS11中UIKit’s Bars的一些新特性:在瀏覽功能上的大標題視圖(向上滑動後標題會回到原來的UI效果)、橫屏狀態下tab上的文字和icon會變爲左右排列。我用iOS11的模擬器體驗了一下Files這個APP的豎屏和橫屏,以下圖所示:session
(command+向左的箭頭讓模擬器橫屏)ide
橫屏時,在iPhone上,tab上的圖標較小,tab bar較小,這樣垂直空間可多放置內容。若是有人看不清楚tab bar上的圖標或文字,能夠經過長按tab bar上的任意item,會將該item顯示在HUD上,這樣能夠清楚的看清icon和text。對tool bar 和 navigation bar同理,長按item也會放大顯示。以下圖顯示:工具
一、UIBarItem佈局
UIBarItem是UI tab bar item和UI bar button item的父類,要想實現上面介紹的效果,只須要爲UIBarItem 設置landscapeImagePhone屬性,在storyboard中也支持這個設置,對於HUD的image須要設置另外一個iOS11新增的屬性:largeContentSizeImage,關於這部分更詳細的討論,能夠參考 WWDC2017 Session 215:What's New in Accessibility學習
二、控制大標題的顯示測試
在UI navigation bar中新增了一個BOOL屬性prefersLargeTitles,將該屬性設置爲ture,navigation bar就會在整個APP中顯示大標題,若是想要在控制不一樣頁面大標題的顯示,能夠經過設置當前頁面的navigationItem的largeTitleDisplayMode屬性;
三、Navigation 集成 UISearchController
把你的UISearchController賦值給navigationItem,就能夠實現將UISearchController集成到Navigation。
四、UINavigationController和滾動交互
滾動的時候,如下交互操做都是由UINavigationController負責調動的:
因此,若是你使用navigation bar,組裝push和pop體驗,你不會獲得searchController的集成、大標題的控制更新和Rubber banding效果,由於這些都是由UINavigationController控制的。
五、UIToolbar and UINavigationBar— Layout
在 iOS 11 中,當蘋果進行全部這些新特性時,也進行了其餘的優化,針對 UIToolbar 和 UINavigaBar 作了新的自動佈局擴展支持,自定義的bar button items、自定義的title均可以經過layout來表示尺寸。 須要注意的是,你的constraints須要在view內部設置,因此若是你有一個自定義的標題視圖,你須要確保任何約束只依賴於標題視圖及其任何子視圖。當你使用自動佈局,系統假設你知道你在作什麼。
六、Avoiding Zero-Sized Custom Views
自定義視圖的size爲0是由於你有一些模糊的約束佈局。要避免視圖尺寸爲0,能夠從如下方面作:
● UINavigationBar 和 UIToolbar 提供位置
● 開發者則必須提供視圖的size,有三種方式:
① 對寬度和高度的約束;
② 實現 intrinsicContentSize;
③ 經過約束關聯你的子視圖;
2、管理margins 和 insets
一、layout margins
基於約束的Auto Layout,使咱們搭建可以動態響應內部和外部變化的用戶界面。Auto Layout爲每個view都定義了margin。margin指的是控件顯示內容部分的邊緣和控件邊緣的距離。 能夠用layoutMargins或者layoutMarginsGuide屬性得到view的margin,margin是視圖內部的一部分。layoutMargins容許獲取或者設置UIEdgeInsets結構的margin。layoutMarginsGuide則獲取到只讀的UILayoutGuide對象。
在iOS11新增了一個屬性:directional layout margins,該屬性是NSDirectionalEdgeInsets結構體類型的屬性:
layoutMargins是UIEdgeInsets結構體類型的屬性:
從上面兩種結構體的對比能夠看出,NSDirectionalEdgeInsets 屬性用leading 和 trailing 取代了以前的 left 和 right。
directional layout margins屬性的說明以下:
例子:當你設置了trailing = 30;當在一個right to left 語言下trailing的值會被設置在view的左邊,能夠經過layout margins的left屬性讀出該值。以下圖所示:
還有其餘一些更新。自從引入layout margins,當將一個view添加到viewController時,viewController會修復view的的layoutMargins爲UIKit定義的一個值,這些調整對外是封閉的。從iOS11開始,這些再也不是一個固定的值,它們實際是最小值,你能夠改變你的view的layoutMargins爲任意一個更大的值。並且,viewController新增了一個屬性:viewRespectsSystemMinimumLayoutMargins,若是你設置該屬性爲"false",你就能夠改變你的layout margins爲任意你想設置的值,包括0,以下圖所示:
二、安全區域(Safe Area)
以下圖:照片應用程序
從iOS 7以來,咱們在整個操做系統中都有這些半透明的bars,蘋果鼓勵咱們經過這些bars繪製內容,咱們是經過viewController 的edgesForExtendedLayout屬性來作這些的。 iOS 7 開始,在 UIViewController中引入的 topLayoutGuide和 bottomLayoutGuide 在 iOS 11 中被廢棄了,取而代之的就是safeArea的概念,safeArea是描述你的視圖部分不被任何內容遮擋的方法。 它提供兩種方式:safeAreaInsets或safeAreaLayoutGuide來提供給你safeArea的參照值,即 insets 或者 layout guide。 safeArea區域以下圖所示:
若是有一個自定義的viewController,你可能要添加你本身的bars,增長safeAreaInsets的值,能夠經過一個新的屬性:addtionalSafeAreaInsets來改變safeAreaInsets的值,當你的viewController改變了它的safeAreaInsets值時,有兩種方式獲取到回調:
3、UIScrollView and UITableView 的新特性
一、 Scroll Views
若是有一些文本位於UI滾動視圖的內部,幷包含在導航控制器中,如今通常navigationContollers會傳入一個contentInset給其最頂層的viewController的scrollView,在iOS11中進行了一個很大的改變,再也不經過scrollView的contentInset屬性了,而是新增了一個屬性:adjustedContentInset,下面的兩張圖的對比可以表示adjustContentInset表示的區域:
新增的contentInsetAdjustmentBehavior屬性用來配置adjustedContentInset的行爲,該結構體有如下幾種類型:
二、Table Views :在iOS 11中默認啓用Self-Sizing
這個應該是UITableView最大的改變。咱們知道在iOS8引入Self-Sizing 以後,咱們能夠經過實現estimatedRowHeight相關的屬性來展現動態的內容,實現了estimatedRowHeight屬性後,獲得的初始contenSize是個估算值,是經過estimatedRowHeight x cell的個數獲得的,並非最終的contenSize,tableView就不會一次性計算全部的cell的高度了,只會計算當前屏幕可以顯示的cell個數再加上幾個,滑動時,tableView不停地獲得新的cell,更新本身的contenSize,在滑到最後的時候,會獲得正確的contenSize。在測試Demo中,建立tableView到顯示出來的過程當中,contentSize的計算過程以下圖:
Self-Sizing在iOS11下是默認開啓的,Headers, footers, and cells都默認開啓Self-Sizing,全部estimated 高度默認值從iOS11以前的 0 改變爲UITableViewAutomaticDimension:
若是目前項目中沒有使用estimateRowHeight屬性,在iOS11的環境下就要注意了,由於開啓Self-Sizing以後,tableView是使用estimateRowHeight屬性的,這樣就會形成contentSize和contentOffset值的變化,若是是有動畫是觀察這兩個屬性的變化進行的,就會形成動畫的異常,由於在估算行高機制下,contentSize的值是一點點地變化更新的,全部cell顯示完後纔是最終的contentSize值。由於不會緩存正確的行高,tableView reloadData的時候,會從新計算contentSize,就有可能會引發contentOffset的變化。iOS11下不想使用Self-Sizing的話,能夠經過如下方式關閉:(前言中提到的問題也是經過這種方式解決的)
iOS11下,若是沒有設置estimateRowHeight的值,也沒有設置rowHeight的值,那contentSize計算初始值是 44 * cell的個數,以下圖:rowHeight和estimateRowHeight都是默認值UITableViewAutomaticDimension 而rowNum = 15;則初始contentSize = 44 * 15 = 660;
三、Table Views:separatorInset 擴展
OS 7 引入separatorInset屬性,用以設置 cell 的分割線邊距,在 iOS 11 中對其進行了擴展。能夠經過新增的UITableViewSeparatorInsetReference枚舉類型的separatorInsetReference屬性來設置separatorInset屬性的參照值。
下圖清晰的展現了這兩種參照值的區別:
四、Table Views 和 Safe Area
有如下幾點須要注意:
● separatorInset 被自動地關聯到 safe area insets,所以,默認狀況下,表視圖的整個內容避免了其根視圖控制器的安全區域的插入。
● UITableviewCell 和 UITableViewHeaderFooterView的 content view 在安全區域內;所以你應該始終在 content view 中使用add-subviews操做。
● 全部的 headers 和 footers 都應該使用UITableViewHeaderFooterView,包括 table headers 和 footers、section headers 和 footers。
五、滑動操做(Swipe Actions)
在iOS8以後,蘋果官方增長了UITableVIew的右滑操做接口,即新增了一個代理方法(tableView: editActionsForRowAtIndexPath:)和一個類(UITableViewRowAction),代理方法返回的是一個數組,咱們能夠在這個代理方法中定義所須要的操做按鈕(刪除、置頂等),這些按鈕的類就是UITableViewRowAction。這個類只能定義按鈕的顯示文字、背景色、和按鈕事件。而且返回數組的第一個元素在UITableViewCell的最右側顯示,最後一個元素在最左側顯示。從iOS 11開始有了一些改變,首先是能夠給這些按鈕添加圖片了,而後是若是實現瞭如下兩個iOS 11新增的代理方法,將會取代(tableView: editActionsForRowAtIndexPath:)代理方法:
這兩個代理方法返回的是UISwipeActionsConfiguration類型的對象,建立該對象及賦值可看下面的代碼片斷:
建立UIContextualAction對象時,UIContextualActionStyle有兩種類型,若是是置頂、已讀等按鈕就使用UIContextualActionStyleNormal類型,delete操做按鈕可以使用UIContextualActionStyleDestructive類型,當使用該類型時,若是是右滑操做,一直向右滑動某個cell,會直接執行刪除操做,不用再點擊刪除按鈕,這也是一個好玩的更新。
滑動操做這裏還有一個須要注意的是,當cell高度較小時,會只顯示image,不顯示title,當cell高度夠大時,會同時顯示image和title。我寫demo測試的時候,由於每一個cell的高度都較小,因此只顯示image,而後我增長cell的高度後,就能夠同時顯示image和title了。見下圖對比:
總結
大概介紹了iOS 11的UI方面的一些更新,大部份內容都用代碼測試過了,有些更新確實是很實用,能夠適配下iOS 11,有的更新可能會給現有APP形成bug,因此學習下這些內容仍是頗有必要的。
參考:
一、Updating Your App for iOS 11 - WWDC 2017 - Session 204 - iOS
二、iOS 8自動調整UITableView和UICollectionView佈局
三、Mysteries of Auto Layout, Part 1 - WWDC2015
四、Mysteries of Auto Layout, Part 2 - WWDC2015
【騰訊WeTest iOS預審工具】
爲了提升IEG蘋果審覈經過率,騰訊專門成立了蘋果審覈測試團隊,打造出iOS預審工具這款產品。通過兩年的內部運營,騰訊內部應用的iOS審覈經過率從平均35%提高到90%+。
現將騰訊內部產品的過審經驗共享給各位。在WeTest騰訊質量開放平臺上可以使用iOS預審工具,點擊連接:http://wetest.qq.com/product/ios 諮詢體驗!
若是使用當中有任何疑問,歡迎聯繫騰訊WeTest 企業QQ:800024531
iOS預審服務
【掃描工具】上傳IPA包、圖片、視頻、應用描述便可進行測試; 多維度自動掃描提審材料的被拒風險;1小時內反饋全面的掃描報告。
【專家預審】騰訊專家爲您遍歷App全部功能模塊;全面暴露App內容被拒風險;跟進問題直至上線(需提供官方拒絕郵件)。
【專家諮詢】資深預審專家一對一服務; 諮詢時間靈活可選,按需購買;有的放矢解 決審覈問題。
【ASO優化】專業團隊多維度深度剖析App的ASO現狀;圍繞App目標用戶羣篩選高 度關聯的關鍵詞;幫助提高App在蘋果應用商店中的曝光率。