iOS11及Xcode9適配問題匯總

來源:互聯網
上載者:User

標籤:contex   mic   navig   lan   重新整理   異常   index   hone   ever   

UIScrollView and UITableView的新特性ScrollView

如果有一些文本位於UI滾動視圖的內部,並包含在導航控制器中,現在一般navigationContollers會傳入一個contentInset給其最頂層的viewController的scrollView,在iOS11中進行了一個很大的改變,不再通過scrollView的contentInset屬性了,而是新增了一個屬性:adjustedContentInset,通過下面兩種圖的對比,能夠表示adjustContentInset表示的地區:

新增的contentInsetAdjustmentBehavior屬性用來配置adjustedContentInset的行為,該結構體有以下幾種類型:

typedef NS_ENUM(NSInteger, UIScrollViewContentInsetAdjustmentBehavior) {      UIScrollViewContentInsetAdjustmentAutomatic,     UIScrollViewContentInsetAdjustmentScrollableAxes,    UIScrollViewContentInsetAdjustmentNever,    UIScrollViewContentInsetAdjustmentAlways,}@property(nonatomic) UIScrollViewContentInsetAdjustmentBehavior contentInsetAdjustmentBehavior;@property(nonatomic, readonly) UIEdgeInsets adjustedContentInset;//adjustedContentInset值被改變的delegate- (void)adjustedContentInsetDidChange; - (void)scrollViewDidChangeAdjustedContentInset:(UIScrollView *)scrollView;

UIScrollViewContentInsetAdjustmentBehavior 是一個枚舉類型,值有以下幾種:

  • automatic 和scrollableAxes一樣,scrollView會自動計算和適應頂部和底部的內邊距並且在scrollView 不可滾動時,也會設定內邊距.
  • scrollableAxes 自動計算內邊距.
  • never不計算內邊距
  • always 根據safeAreaInsets 計算內邊距
TableView1.UITableview UICollectionView MJRefresh下拉重新整理錯亂或是莫名有20空隙的問題
if (@available(iOS 11.0, *)) {    _tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;    _tableView.contentInset = UIEdgeInsetsMake(64, 0, 49, 0);//iPhoneX這裡是88    _tableView.scrollIndicatorInsets = _tableView.contentInset;}

如果改完後運行無效果 可以嘗試Clean一下工程再運行, 很多小夥伴都遇到這樣的問題了, 你不妨也試以試.

2.在iOS 11中預設啟用Self-Sizing 未使用AutoLayout的TableView中的高度會出現問題.

Self-Sizing在iOS11下是預設開啟的,Headers, footers, and cells都預設開啟Self-Sizing,所有estimated 高度預設值從iOS11之前的 0 改變為UITableViewAutomaticDimension.

如果目前項目中沒有使用estimateRowHeight屬性,在iOS11的環境下就要注意了,因為開啟Self-Sizing之後,tableView是使用estimateRowHeight屬性的,這樣就會造成contentSizecontentOffset值的變化,如果是有動畫是觀察這兩個屬性的變化進行的,就會造成動畫的異常,因為在估算行高機制下,contentSize的值是一點點地變化更新的,所有cell顯示完後才是最終的contentSize值。因為不會緩衝正確的行高,tableView reloadData的時候,會重新計算contentSize,就有可能會引起contentOffset的變化。iOS11下不想使用Self-Sizing的話,可以通過以下方式關閉:

self.tableView.estimatedRowHeight = 0;self.tableView.estimatedSectionHeaderHeight = 0;self.tableView.estimatedSectionFooterHeight = 0;
3.TableView的separatorInset擴充

iOS 7 引入separatorInset屬性,用以設定 cell 的分割線邊距,在 iOS 11 中對其進行了擴充。可以通過新增的UITableViewSeparatorInsetReference枚舉類型的separatorInsetReference屬性來設定separatorInset屬性的參照值.

通過下面的參考圖可以看出他們的區別:

4. TableView和SafeArea(安全區)

有以下幾點需要注意:

  • separatorInset 被自動地關聯到 safe area insets,因此,預設情況下,表視圖的整個內容避免了其根視圖控制器的安全區域的插入。
  • UITableviewCell 和 UITableViewHeaderFooterView的 contentview 在安全區域內;因此你應該始終在 contentview 中使用add-subviews操作。
  • 所有的 headers 和 footers 都應該使用UITableViewHeaderFooterView,包括 table headers 和 footers、section headers 和 footers。
5. TableView的滑動操作

在iOS8之後,蘋果官方增加了UITableVIew的右滑操作介面,即新增了一個代理方法tableView: editActionsForRowAtIndexPath:和一個類UITableViewRowAction,代理方法返回的是一個數組,我們可以在這個代理方法中定義所需要的操作按鈕(刪除、置頂等),這些按鈕的類就是UITableViewRowAction。這個類只能定義按鈕的顯示文字、背景色、和按鈕事件。並且返回數組的第一個元素在UITableViewCell的最右側顯示,最後一個元素在最左側顯示。從iOS 11開始有了一些改變,首先是可以給這些按鈕添加圖片了,然後是如果實現了以下兩個iOS 11新增的代理方法,將會取代tableView: editActionsForRowAtIndexPath:代理方法:

這兩個代理方法返回的是UISwipeActionsConfiguration類型的對象,建立該對象及賦值可看下面的程式碼片段:

- ( UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath {    //刪除    UIContextualAction *deleteRowAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleDestructive title:@"delete" handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {        [self.titleArr removeObjectAtIndex:indexPath.row];        completionHandler (YES);    }];    deleteRowAction.image = [UIImage imageNamed:@"icon_del"];    deleteRowAction.backgroundColor = [UIColor blueColor];    UISwipeActionsConfiguration *config = [UISwipeActionsConfiguration configurationWithActions:@[deleteRowAction]];    return config;}
typedef NS_ENUM(NSInteger, UIContextualActionStyle) {    UIContextualActionStyleNormal,    UIContextualActionStyleDestructive} NS_SWIFT_NAME(UIContextualAction.Style)

建立UIContextualAction對象時,UIContextualActionStyle有兩種類型,如果是置頂、已讀等按鈕就使用UIContextualActionStyleNormal類型,delete操作按鈕可使用UIContextualActionStyleDestructive類型,當使用該類型時,如果是右滑操作,一直向右滑動某個cell,會直接執行刪除操作,不用再點擊刪除按鈕,這也是一個好玩的更新.

typedef NS_ENUM(NSInteger, UIContextualActionStyle) {    UIContextualActionStyleNormal,    UIContextualActionStyleDestructive} NS_SWIFT_NAME(UIContextualAction.Style)

滑動操作這裡還有一個需要注意的是,當cell高度較小時,會只顯示image,不顯示title,當cell高度夠大時,會同時顯示image和title。我寫demo測試的時候,因為每個cell的高度都較小,所以只顯示image,然後我增加cell的高度後,就可以同時顯示image和title了。見對比:

iOS11中 UIKit’s Bars 上的變化

WWDC通過iOS新增的檔案管理App:Files開始介紹,在Files這個APP中能夠看到iOS11中UIKit’s Bars的一些新特性:在瀏覽功能上的大標題視圖(向上滑動後標題會回到原來的UI效果)、橫屏狀態下tab上的文字和icon會變為左右排列:

在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

  • 控制大標題的顯示

UINavigationbar中新增了一個BOOL屬性prefersLargeTitles,將該屬性設定為ture,navigationbar就會在整個APP中顯示大標題,如果想要在控制不同頁面大標題的顯示,可以通過設定當前頁面的navigationItemlargeTitleDisplayMode屬性.

navigationItem.largeTitleDisplayMode typedef NS_ENUM(NSInteger, UINavigationItemLargeTitleDisplayMode) {  /// 自動模式依賴上一個 item 的特性UINavigationItemLargeTitleDisplayModeAutomatic,/// 針對當前 item 總是啟用大標題特性UINavigationItemLargeTitleDisplayModeAlways,/// Never UINavigationItemLargeTitleDisplayModeNever,}
在 Navigation 整合 UISearchController

把你的UISearchController賦值給navigationItem,就可以實現將UISearchController整合到 Navigation.

navigationItem.searchController  //iOS 11 新增屬性navigationItem.hidesSearchBarWhenScrolling //決定滑動的時候是否隱藏搜尋方塊;iOS 11 新增屬性
UINavigationController和滾動互動

滾動的時候,以下互動操作都是由UINavigationController負責調動的:

UIsearchController搜尋方塊效果更新大標題效果的控制Rubber banding效果 //當你開始往下拉,大標題會變大來回應那個滾輪

所以,如果你使用navigation bar,組裝一些整體push和pop體驗,你不會得到searchController的整合、大標題的控制更新和Rubber banding效果,因為這些都是由UINavigationController控制的。

Margins 和 Insets

基於約束的Auto Layout, 使我們搭建能夠動態響應內部和外部變化的使用者介面. Auto Layout為每一個view都定義了marginmargin指的是控制項顯示內容部分的邊緣和控制項邊緣的距離.
可以用layoutMargins或者layoutMarginsGuide屬性獲得viewmarginmargin是視圖內部的一部分. layoutMargins允許擷取或者設定UIEdgeInsets結構的marginlayoutMarginsGuide則擷取到唯讀UILayoutGuide對象.

在iOS11新增了一個屬性:directional layout margins,該屬性是NSDirectionalEdgeInsets結構體類型的屬性:

typedef struct NSDirectionalEdgeInsets {      CGFloat top, leading, bottom, trailing;} NSDirectionalEdgeInsets API_AVAILABLE(ios(11.0),tvos(11.0),watchos(4.0));

layoutMarginsUIEdgeInsets結構體類型的屬性:

typedef struct UIEdgeInsets {  CGFloat top, left, bottom, right;} UIEdgeInsets;

從上面兩種結構體的對比可以看出, NSDirectionalEdgeInsets屬性用leading 和 trailing 取代了之前的 left 和 right.

directional layout margins屬性的說明如下:

directionalLayoutMargins.leading is used on the left when the user interface direction is LTR and on the right for RTL.Vice versa for directionalLayoutMargins.trailing.

例子: 當你設定了trailing = 30; 當在一個right to left 語言下trailing的值會被設定在view的左邊, 可以通過layoutMarginleft屬性讀出該值. 如所示:

還有其他一些更新. 自從引入layout margins, 當將一個view添加到viewController時, viewController會修改viewlayoutMargins為UIKit定義的一個值, 這些調整對外是封閉的. 從iOS11開始, 這些不再是一個固定的值, 它們實際是最小值, 你可以改變viewlayoutMargins為任意一個更大的值. 而且, viewController新增了一個屬性: viewRespectsSystemMinimumLayoutMargins, 如果你設定該屬性為false, 你就可以改變你的layoutMargins為任意你想設定的值, 包括0, 如所示:

iOS11及Xcode9適配問題匯總

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.