iOS 11 安全區(qū)域適配

前言

之前的理解比較模糊,有些地方都理解錯(cuò)了,這次學(xué)習(xí)完整理下。

iOS 7以后的變化

iOS 7之后,UIViewController新增了三個(gè)屬性來進(jìn)行頁(yè)面布局:

edgesForExtendedLayout (可延伸的邊緣設(shè)置

iOS 7之后默認(rèn)開始使用全屏布局,作用于Controller的View,不論是嵌入到UINavigationController還是UITabbarController,根控制器Controller的View都會(huì)鋪滿整個(gè)屏幕,并且NavigationBar默認(rèn)半透明,而edgesForExtendedLayout屬性由UIRectEdge枚舉賦值,默認(rèn)是UIRectEdgeAll,效果如下:


UIRectEdgeAll.png

可以看到self.view已經(jīng)鋪滿了整個(gè)屏幕,紅色部分已經(jīng)浸入到NavigationBar和Tabbar,在self.view上添加子視圖如果不想被遮擋,需要考慮NavigationBar和Tabbar的高度。
UIRectEdge枚舉:

typedef NS_OPTIONS(NSUInteger, UIRectEdge) {
    UIRectEdgeNone   = 0,
    UIRectEdgeTop    = 1 << 0,  只有頂部延伸
    UIRectEdgeLeft   = 1 << 1,  只有左邊延伸
    UIRectEdgeBottom = 1 << 2,  只有底部延伸
    UIRectEdgeRight  = 1 << 3,  只有右邊延伸
    UIRectEdgeAll    = UIRectEdgeTop | UIRectEdgeLeft | UIRectEdgeBottom | UIRectEdgeRight
} NS_ENUM_AVAILABLE_IOS(7_0);

注意下,此屬性只作用于嵌入在容器中的控制器,其他地方不適用。

automaticallyAdjustsScrollViewInsets (自動(dòng)適應(yīng)滾動(dòng)視圖內(nèi)邊距?

這個(gè)屬性的作用于Controller的View上添加的ScrollView及其子類,通過控制ScrollView的contentInset值,讓ScrollView包含的內(nèi)容不會(huì)被Bar遮擋,默認(rèn)為YES。
下面是默認(rèn)為YES的情況:


默認(rèn)為YES_1.png
默認(rèn)為YES_2.png

可以看到雖然紅色的TableView鋪滿了全屏,但是所包含的內(nèi)容并沒有被NavigationBar和TabBar所遮擋。
下面是為NO的情況:


修改為NO_1.png
修改為NO_2.png

可以看到TableView的內(nèi)容已經(jīng)被Bar擋住。

navigationBar.translucent (導(dǎo)航欄的透明度)

這個(gè)屬性用于控制導(dǎo)航欄是否為半透明狀態(tài),默認(rèn)為YES,同時(shí)他會(huì)影響到self.view的布局問題。當(dāng)設(shè)置self.navigationController.navigationBar.translucent = NO時(shí),self.view的布局并不會(huì)從頂部開始,而是從NavigationBar的底部開始。
這個(gè)時(shí)候再設(shè)置edgesForExtendedLayout = UIRectEdgeAll或者UIRectEdgeTop,都是沒有作用的!也就是說,當(dāng)設(shè)置導(dǎo)航欄不透明,根視圖延伸的屬性也起不到作用了。由此引出了extendedLayoutIncludesOpaqueBars。

extendedLayoutIncludesOpaqueBars (包括不透明Bars的延伸布局

這個(gè)屬性的作用是,當(dāng)導(dǎo)航欄不透明的時(shí)候,self.view的布局要不要延伸到Bar的下面鋪滿屏幕,默認(rèn)為NO。
但是!edgesForExtendedLayout會(huì)對(duì)這個(gè)屬性有影響。

先設(shè)置

// 導(dǎo)航欄不透明
self.navigationController.navigationBar.translucent = NO;
// 布局延伸包括不透明導(dǎo)航欄
self.extendedLayoutIncludesOpaqueBars = YES;

如果

// self.view鋪滿屏幕
self.edgesForExtendedLayout = UIRectEdgeAll;

效果如下:


UIRectEdgeAll.png

如果

// self.view不鋪滿屏幕
self.edgesForExtendedLayout = UIRectEdgeNone;

效果如下:


UIRectEdgeNone.png

對(duì)以上四個(gè)屬性的總結(jié):

1:當(dāng)導(dǎo)航欄半透明時(shí)(navigationBar.translucent = YES),self.view的布局只受edgesForExtendedLayout屬性影響。
2:當(dāng)導(dǎo)航欄不透明時(shí)(navigationBar.translucent = NO),self.view的布局受edgesForExtendedLayout和extendedLayoutIncludesOpaqueBars兩個(gè)屬性影響。
3:automaticallyAdjustsScrollViewInsets并不影響self.view的布局,只是當(dāng)self.view添加ScrollView及其子類的時(shí)候,為了讓包含的內(nèi)容不被Bar遮住而調(diào)整contentInset的值。

iOS11的變化

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容