iOS11 & iPhone X 適配指南?

聲明:這篇文章轉載 *zombieEngineer * [Cocoa開發者社區]僅供大家參考學習使用,也方便自己學習,收藏。

蘋果WWDC開發者大會上,終于發布了大家期待已久的iOS 11,有些新特性功能確實出人意料。不過大的方面蘋果貌似也就 AR 和 GM 機器學習了,9月13日凌晨1點,蘋果開了新品發布會,相信大家都已經知道Phone X 的劉海了,看起來不是很雅觀,對于iOS開發者來說,適配工作也帶來了麻煩,iOS11在新舊API 方面做了新的改動,未來App Store就會出現很多大量的APP更新,針對iOS11和iPhone X的適配。

下面針對已經了解的出現的問題進行適配的說明。

屏幕未充滿?

相信一部分開發者已經在著手適配iPhone X 和iOS11 了,xcode9測試版運行自己的項目會發現項目沒有充滿屏幕,上下會有黑色區域的情況,大家別慌,這是沒有設置對應的啟動圖,iPhone X對應像素 1125 * 2436
大家可以自己添加圖片或者準備一張尺寸:1125 * 2436的啟動圖片, 移動到LaunchImage的Finder目錄中, 并在LaunchImage中的Contents.json文件中增加 (注意Json格式):

{
    "extent" : "full-screen",
    "idiom" : "iphone",
    "subtype" : "2436h",
    "filename" : "圖片名字.png",
    "minimum-system-version" : "11.0",
    "orientation" : "portrait",
    "scale" : "3x"
}

UITableview UICollectionView MJRefresh下拉刷新錯亂

iOS11 UIScrollView and UITableView的新特性

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

contentInsetAdjustmentBehavior屬性有以下幾個枚舉值

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;
  • 1 automatic 和scrollableAxes一樣,scrollView會自動計算和適應頂部和底部的內邊距并且在scrollView 不可滾動時,也會設置內邊距.

  • 2 scrollableAxes 自動計算內邊距.

  • 3 never不計算內邊距

  • 4 always 根據safeAreaInsets 計算內邊距

在我們項目中寫tableview的時候可以加下面的代碼來解決此問題

if (@available(iOS 11.0, *)) {
    _tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    _tableView.contentInset = UIEdgeInsetsMake(64, 0, 49, 0);//iPhoneX這里是88
    _tableView.scrollIndicatorInsets = _tableView.contentInset;
}

在我自己項目中,我發現如果用的系統的導航欄的話距離上部可為0反而加上會有問題,列表會下移你設置的數值

_tableView.contentInset = UIEdgeInsetsMake(0, 0, 49, 0);

// 實際項目中這樣也有出現列表的下面可能會被遮擋(針對部分項目,視情況而定) 針對我自己的項目我設置了向下導航欄的高度看似沒有問題了

tableView cell高度問題和頭視圖尾視圖會有很大間隙

這個應該是UITableView最大的改變。我們知道在iOS8引入Self-Sizing 之后,我們可以通過實現estimatedRowHeight相關的屬性來展示動態的內容,實現了estimatedRowHeight屬性后,得到的初始contenSize是個估算值,是通過estimatedRowHeight x cell的個數得到的,并不是最終的contenSize,tableView不會一次性計算所有的cell的高度了,只會計算當前屏幕能夠顯示的cell個數再加上幾個,滑動時,tableView不停地得到新的cell,更新自己的contenSize,在滑到最后的時候,會得到正確的contenSize。

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

@property (nonatomic) CGFloat estimatedRowHeight NS_AVAILABLE_IOS(7_0); 

// default is UITableViewAutomaticDimension, set to 0 to disable

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

通過以下方式關閉:

self.tableView.estimatedRowHeight = 0;
self.tableView.estimatedSectionHeaderHeight = 0;
self.tableView.estimatedSectionFooterHeight = 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區域如圖所示:

iOS11 為UIViewController和UIView增加了一個新的方法

 - (void)viewSafeAreaInsetsDidChange;

這個方法如名字一樣 在安全區域改變后會被調用, 我們可以在需要適配的UIViewController和UIView中重寫這個方法, 并且在這個方法中來根據safeAreaInsets屬性更新子視圖控件的布局位置.

這里有一點要注意的是當UIViewController調用- (void)viewDidLoad時它的所有子視圖的safeAreaInsets屬性都等于UIEdgeInsetsZero, 也就是說在- (void)viewSafeAreaInsetsDidChange;方法調用前 是無法通過當前視圖控制器的子視圖獲取到safeAreaInsets的, 不過獲取當前window對象的safeAreaInsets屬性用來計算也是可以的, 但是不建議這么做, 一個視圖控制器的子視圖的處理當然要以它所在的控制器為準.

(void)viewSafeAreaInsetsDidChange在UIViewController中第一次調用的時間是在- (void)viewWillAppear:(BOOL)animated調用之后, 在- (void)viewWillLayoutSubviews調用之前.

當然如果你要改變一個UIViewController的safeAreaInsets值, 可以通過設置addtionalSafeAreaInsets屬性來實現, 例如你要自定義一些特殊的樣式時.

如果你改變了一個UIViewController的safeAreaInsets屬性值, - (void)viewSafeAreaInsetsDidChange也會被調用.

采用SB或者xib 布局 Autolayout 視圖的 top 和 bottom 一般參照的是 Top Layout Guide 和 Bottom Layout Guide. 但是iOS11 廢棄了改用安全區域(SafeArea)做參考來做適配

滑動刪除會蹦?

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

// Swipe actions
// These methods supersede -editActionsForRowAtIndexPath: if implemented
- (nullable UISwipeActionsConfiguration *)tableView:(UITableView *)tableView leadingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath
- (nullable UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath

這兩個代理方法返回的是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;
}

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

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

目前暫時遇到的問題解決,還是等20號正式版推出再做詳細的適配和更改,畢竟測試版的問題和bug 還是很多的。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,837評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,196評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,688評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,654評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,456評論 6 406
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,955評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,044評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,195評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,725評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,608評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,802評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,318評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,048評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,422評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,673評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,424評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,762評論 2 372

推薦閱讀更多精彩內容