深入理解代替单纯记忆
Top/Bottom Layout Guide
-
最开始(iOS 7)是
NSLayoutConstraint表示约束,直接加到视图中生效 -
后来(iOS 9),由于直接添加约束的API太冗长,于是出现了
NSLayoutAnchor的一套APIview1.topAnchor.constraint(equalTo: view2.centerYAnchor).isActive = true -
同时出现了
Top/Bottom Layout Guide,为的是解决在与root view of viewcontroller布局时,躲开顶部导航栏、状态栏的问题(因为如果没有这两个guide,代码中可能会出现一些magic number) -
topLayoutGuide是
UILayoutSupportprotocol类型- 该类型提供了
length用于frame布局 - 也提供了
topAnchor、bottomAnchor、length用于autolayout布局
- 该类型提供了
iOS 11及之后便
deprecated了,取而代之的是更好用的safeArea
LayoutMargins
一种在view、subviews之间起作用的相对布局机制;可以看作是不建议subview布局的区域
- 每个view都有
layoutMargins和layoutMarginsGuide两个属性(对应frame和autolayout两种布局方式) - 该属性告诉subViews,我建议你们布局时不要遮盖到
layoutMargins表示的范围 - 那么根据上面的思想
- 在使用
layoutMarginsGuide或在IB中选择相对于margin布局时,当父视图的layoutMargins发生改变时,子视图位置会相对改变 - 除了上面说的联动变化,当
preservesSuperviewLayoutMargins属性为true时(默认false),也会联动变化。变化是,设置该属性的view,在subview布局时,会考虑view.superView所设置的layoutMargins,比如view.superView的layoutMargins设置的很大,以至于subview可能会布局到view.superview不希望的地方,那开启此属性就会自动调整subview位置
- 在使用
- iOS 11起引入了
directionalLayoutMargins,是layoutMargin的升级版,layoutMaring在水平方向只有left和right,但directionalLayoutMargins使用了leading和trailing,支持虽不同阅读方向的语言的环境下动态配置横向margin
Positioning Content Within Layout Margins
safeArea
- iOS 11引入,对每个UIView,都有一个safeArea,它表示了能够不被其他控件遮挡的可布局的安全区域
- UIViewController的view的safeArea会考虑到status bar、navigation bar和tab bar
- safeArea和layoutMargin类似,同样体现在autolayout和非autolayout两方面
safeAreaLayoutGuide用于autolayoutsafeAreaInsets用于frame布局
- safeArea的这两个属性是无法修改的
- 但UIViewController的view可以通过设置
additionalSafeAreaInsets来扩展safearea
- 但UIViewController的view可以通过设置
Positioning Content Relative to the Safe Area
safeArea vs layoutMargin
截止到目前(写文章时最新的iOS系统是13版本)
-
safearea的产生并不是用来取代layoutMargin的,从layoutMargin并没有被废弃能够看出,这两套机制都可以正常的work
-
layoutMargin可以被修改,safeArea不可以
-
两者的唯一联系是,
insetsLayoutMarginsFromSafeArea当为true时,且layoutMargin在safearea范围以外时,layoutMargin会自动调整为safeArea的大小 -
Layout Guide, Margins, Insets and Safe Area demystified on iOS 10 & 11