標籤:dir lin 大小 部分 roo back 完全 左右 上下
safeArea
即可以正常顯示內容的部分。?
?
可以通過
additionalSafeAreaInsets
來調整 safeArea 的大小。
?
經過調整,範圍如下:
self.additionalSafeAreaInsets = UIEdgeInsets.init(top: 20, left: 30, bottom: 0, right: 10)
?
通過
safeAreaLayoutGuide
建立約束
bgView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), bgView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor), bgView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor), bgView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor)
subView 的 safeAreaInsets
- 完全在內部的,
safeAreaInsets
為 0
- 部分在 supview 內部,但在 safeArea 之外的,
safeAreaInsets
為之間的大小
- 在 superview 之外的,為父 view
safeAreaInsets
的大小,不會延伸出去
?
view safeArea: UIEdgeInsets(top: 64.0, left: 30.0, bottom: 83.0, right: 10.0)bgview SafeArea: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0)topview SafeArea: UIEdgeInsets(top: 64.0, left: 10.0, bottom: 0.0, right: 0.0)rightView SafeArea: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 10.0)
如上所示,藍色完全在 rootview 的 safeArea 之內,所以 safeAreaInsets
為0.
topview 在 rootview 的 bounds 之內,但是在 safeArea 之外,所以 safeAreaInsets
反映了在 rootview 的 bounds 之內, safeArea 之外的地區。
rightView 的右邊已經超出了螢幕範圍,所以 safeAreaInsets
的右邊是 rootview 的 safeAreaInsets
的右邊,不會繼續超出。
Margin
即內間距?
使用
layoutMarginsGuide
來建立約束
bgView.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor),bgView.bottomAnchor.constraint(equalTo: view.layoutMarginsGuide.bottomAnchor),bgView.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor),bgView.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor)
insetsLayoutMarginsFromSafeArea 屬性
When the value of this property is true, any margins that are outside the safe area are automatically modified to fall within the safe area boundary. The default value of this property is true. Changing the value to false allows your margins to remain at their original locations, even when they are outside the safe area.
即這個屬性可以保證不落在 safeArea 地區之外
?
// 這裡可以修改 layoutmargin topView.layoutMargins = UIEdgeInsets.init(top: 0, left: 0, bottom: 0, right: 0) [topView, rightView].forEach { (viewa) in let label = UILabel.init() label.translatesAutoresizingMaskIntoConstraints = false label.backgroundColor = UIColor.purple viewa?.addSubview(label) label.text = "tesx" let labelConstranits = [label.topAnchor.constraint(equalTo: viewa!.layoutMarginsGuide.topAnchor), label.leftAnchor.constraint(equalTo: viewa!.layoutMarginsGuide.leftAnchor)] NSLayoutConstraint.activate(labelConstranits) // 如果這個是false,那麼topview中的label,可以出現在safeArea地區之外 topView.layoutMargins維持為0 // 如果這個是true,那麼topview的lable一定在safeArea之內。topView.layoutMargins也會變化 viewa!.insetsLayoutMarginsFromSafeArea = false }
如所示,lable 落在了 safeArea 之外,如果把 insetsLayoutMarginsFromSafeArea
設定為 true,結果如下:
?
值得注意的是,建立約束時,一定要用 layoutMarginsGuide
,否則,即使insetsLayoutMarginsFromSafeArea
設定為 true,也會落在 safeArea 之外。
preservesSuperviewLayoutMargins
When the value of this property is true, the superview’s margins are also considered when laying out content. This margin affects layouts where the distance between the edge of a view and its superview is smaller than the corresponding margin. For example, you might have a content view whose frame precisely matches the bounds of its superview. When any of the superview’s margins is inside the area represented by the content view and its own margins, UIKit adjusts the content view’s layout to respect the superview’s margins. The amount of the adjustment is the smallest amount needed to ensure that content is also inside the superview’s margins.
文檔寫的有點稀裡糊塗的,我們看一個例子。?
- 藍色的 view 上加了一層紫色的 view, 紫色的 view 上加了白色的 view
- 藍色 view 的
layoutMargins
為 (top: 100, left: 50, bottom: 100, right: 40)
- 紫色 view 的約束為頂部的底部差10,左右展開
- 紫色 view 的
preservesSuperviewLayoutMargins
為 true
- 白色 view 的約束為上下左右和紫色 view 的
layoutMarginsGuide
對齊
- 紫色 view 的
layoutMargins
為 (top: 0, left: 0, bottom: 0, right: 0)
如果 preservesSuperviewLayoutMargins
為 false,那麼白色 view 和紫色 view 大小完全一致。由於這個屬性為 true,所以紫色 view 在布局時,考慮到了父 view 的 layoutMargins
,因此白色 view 大小被縮減了。
viewRespectsSystemMinimumLayoutMargins
系統的 VC 有一個預設的最小內間距,唯讀不可寫,稱為 systemMinimumLayoutMargins
。
即使我們設定了 rootview 的 directionalLayoutMargins
,如果太小的話,系統會會退到系統預設的最小間距。
?
如上所示,VC 的 rootView 的內間距被設為了零,按照 layoutMarginsGuide
建立約束,左右仍然有內間距。是因為這個VC 的 systemMinimumLayoutMargins
為 (top: 0.0, leading: 16.0, bottom: 0.0, trailing: 16.0)
。
如果把 viewRespectsSystemMinimumLayoutMargins
設定為 false,就可以擴充到邊緣了。
?
參考
- UIKit: Apps for Every Size and Shape
- Preserves Superview Layout Margins
- imanoupetit/Margins-And-Safe-Area
- demo
UIKit: Apps for Every Size and Shape