前言
Safe areas的作用是幫助我們將views放置在整個(gè)視圖中可見(jiàn)的正確的位置昆婿。UIKit定義下的View controllers中常常會(huì)有一部分特殊的views會(huì)被放置在最上方跑揉。例如:導(dǎo)航控制器NavigationController的NavigationBar就被放置在視圖的最頂部。即使有些時(shí)候這些放置在最頂部的views是透明的或者部分透明的蛮原,但是它仍然會(huì)遮蓋住在此位置的其他內(nèi)容仰剿。(注:此處最頂部不是指Y軸坐標(biāo)為0的頂部创淡,而是視圖層級(jí)的頂部,導(dǎo)航欄的位置永遠(yuǎn)在視圖最頂部不會(huì)被其他view遮蓋啄纤薄)
使用Safe areas來(lái)幫助我們布置我們的內(nèi)容琳彩。每個(gè)view都包含一個(gè)自身的layout guide(這一部分可以參考 safeAreaLayoutGuide
),我們可以用它來(lái)創(chuàng)建對(duì)view 的約束部凑,如果你并沒(méi)有使用 Auto Layout 來(lái)定位你的view露乏,我們可以通過(guò) safeAreaInsets
屬性來(lái)獲得內(nèi)部的值加以處理達(dá)到我們的目的。
圖1展示了日歷App的兩個(gè)頁(yè)面涂邀,并且解釋了這兩個(gè)不同的頁(yè)面下關(guān)聯(lián)的Safe area的部分瘟仿。
擴(kuò)展安全區(qū)域并包括自定義的views
我們可以定義一個(gè)容器視圖控制器container viewcontroller并通過(guò)添加子控制器child viewcontroller來(lái)將子控制器的視圖展示出來(lái)(注:這一部分的容器控制器其實(shí)代表的是諸如:NavigationController、TabbarController之類的視圖控制器)比勉。之后劳较,更新child viewcontroller的safe area來(lái)排除被container viewcontroller視圖遮蓋的部分。UIKit下的container viewcontroller已經(jīng)自動(dòng)調(diào)整了child viewcontroller的安全區(qū)域以便正確布局浩聋。例如:NavigationController 會(huì)自動(dòng)調(diào)整其之下的child viewcontroller的safe area以便放置NavigationBar观蜗。如果我們想要調(diào)整一個(gè)child viewcontroller的safe area可以通過(guò)修改additionalSafeAreaInsets
屬性。
假設(shè)我們定義了一個(gè)container controller并在屏幕底部和邊緣放置了我們自定義的views衣洁,如圖2
因?yàn)檫@兩個(gè)custom view將會(huì)遮蓋child viewcontroller 中的內(nèi)容墓捻。所以我們必須調(diào)整child viewcontroller的safe area以便正確布局。
下面的代碼是container view controller中的 viewDidAppear(_:)
方法坊夫,這個(gè)方法的作用就是調(diào)整child viewcontroller中的safe area砖第。在這個(gè)方法中修改safe area的原因是在視圖被添加到view hierarchy
之前撤卢,safeAreaInsets
這個(gè)值都是不準(zhǔn)確的。
override func viewDidAppear(_ animated: Bool) {
var newSafeArea = view.safeAreaInsets
// Adjust the safe area to accommodate
// the width of the side view.
if let sideViewWidth = sideView?.bounds.size.width {
newSafeArea.right += sideViewWidth
}
// Adjust the safe area to accommodate
// the height of the bottom view.
if let bottomViewHeight = bottomView?.bounds.size.height {
newSafeArea.bottom += bottomViewHeight
}
// Adjust the safe area insets of the
// embedded child view controller.
let child = self.childViewControllers[0]
child.additionalSafeAreaInsets = newSafeArea
}