Usually, when we adapt the special-shaped screen, we may use itsafeAreaInsets
。 If the timing is wrong,safeAreaInsets
There will also be problems with the value of. Maybe you can usekey window
ofsafeAreaInsets
Or you can rewrite itfunc safeAreaInsetsDidChange()
Method to modify the layout at the right time, but these operations are always troublesome and uncomfortable to use.
Is there a better way? Let’s first introduce two properties.
layoutMargins
The default spacing to use when laying out content in the view.
IOS 8 is newly added. Through the attribute name, we can understand what it is. In short, it is the margin in the layout.

layoutMarginsGuide
A layout guide representing the view’s margins.
IOS 9 new, you canlinkSee more information.
How to use
Here are three use cases to summarize usage.
Example 1
let pinkView = UIView()
pinkView.backgroundColor = .systemPink
pinkView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(pinkView)
view.addConstraints([
NSLayoutConstraint(
item: pinkView,
attribute: .leftMargin,
relatedBy: .equal,
toItem: view,
attribute: .leftMargin,
multiplier: 1,
constant: 0
),
NSLayoutConstraint(
item: pinkView,
attribute: .rightMargin,
relatedBy: .equal,
toItem: view,
attribute: .rightMargin,
multiplier: 1,
constant: 0
),
NSLayoutConstraint(
item: pinkView,
attribute: .topMargin,
relatedBy: .equal,
toItem: view,
attribute: .topMargin,
multiplier: 1,
constant: 0
),
NSLayoutConstraint(
item: pinkView,
attribute: .bottomMargin,
relatedBy: .equal,
toItem: view,
attribute: .bottomMargin,
multiplier: 1,
constant: 0
)
])
view.layoutMargins = UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20)
have access toSnapKit
To simplify the following code:
let pinkView = UIView()
pinkView.backgroundColor = .systemBlue
pinkView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(pinkView)
pinkView.snp.makeConstraints {
$0.edges.equalTo(self.view.layoutMarginsGuide)
}
layoutMargins = UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20)
self.view.layoutMarginsGuide
It can also be replaced withself.view.snp.margins
, the two methods are equivalent.
At the same time,SnapKit
You can also control four margins separately, usingleftMargin
、rightMargin
、topMargin
、bottomMargin
Separate control.


As can be seen from the above picture, although we set the four margins to be 20pt. However, the actual display on different models shows that the visible margins are different, and the horizontal and vertical screens are also different.
It is necessary to mention the safe area here, as we can seepinkView
The view of is fully displayed in the safe area. In fact, when we set the layout code, we did not consider the security area of various situations, but the system added it for us. I think, here, the good use of this layout is self-evident.
Use case 2
We often encounter the need to add a toolbar at the bottom of the page, which needs to be adapted to the special-shaped screen. That is, on the special-shaped screen, the bottom of it is left blank to make the operation related elements in the safe area.
We can layout in this way to achieve the purpose of adaptation:
class BottomBar: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .white
layoutMargins = UIEdgeInsets(top: 15, left: 15, bottom: 15, right: 15)
addSubview(button)
button.snp.makeConstraints {
$0.width.equalTo(90)
$0.height.equalTo(36)
$0.right.equalTo(self.snp.rightMargin)
$0.top.equalTo(self.snp.topMargin)
$0.bottom.equalTo(self.snp.bottomMargin)
}
}
...
}
class ViewController: UIViewController {
let bottomView = BottomBar()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(bottomView)
bottomView.snp.makeConstraints {
$0.left.bottom.right.equalTo(0)
}
}
}


You can see that the toolbar at the bottom has been adapted. We don’t need to do other operations.
The above code is fixed by a sizebutton
Fill up the bottom toolbar and we’llbutton
Set the bottom constraint to$0.bottom.equalTo(self.snp.bottomMargin)
, set the container viewlayoutMargins.bottom = 15
, on the actual effect picture, the system has automatically addedsafeAreaInsets.bottom
。 At the same time, in the horizontal screen state, the safety distance is added to the bottom and right.
Use case 3
On the basis of use case 2, we add a toolbar.
view.addSubview(bottomView)
bottomView.snp.makeConstraints {
$0.left.bottom.right.equalTo(0)
}
let bottomView = BottomBar()
view.addSubview(bottomView)
bottomView.snp.makeConstraints {
$0.left.right.equalTo(0)
$0.bottom.equalTo(self.bottomView.snp.top).offset(-1)
}

Obviously, we see that the bottom of the toolbar above is not addedsafeAreaInsets.bottom
, but on the rightsafeAreaInsets.right
。
Here, we can conclude:
When any edge of the view intersects with the edge of the screen, using the layoutmarginsguide layout, the system will add the margin of the security area to the margin of the corresponding edge。
In addition, we can dynamically adjust it in subsequent uselayoutMargins
When adjusted, the view willRefresh corresponding margins in real timeYou can even animate this change.
Isn’t it nice?
summary
This layout is highly recommended. Through the above example, we can experience its beauty. In this process, we do not need to considersafeAreaInsets
, just understandlayoutMargins
andlayoutMarginsGuide
And use it correctly.
This article is just a brief introductionlayoutMargins
andlayoutMarginsGuide
Part of it is used to attract jade. As for its use, I think only when you really use it, you will feel the benefits of this design.
It is worth noting that IOS 11 launcheddirectionalLayoutMargins
, that islayoutMargins
There is no big difference in the use of substitutes. It’s just another enumeration. Those who are interested can try it by themselves. There is still a lot of research on the layout. The correct use of the methods provided by the system can enable us to write more robust code, and enable us to adapt to different screens and different devices.
If this article is helpful to you, you might as well like it! thank you ❤ ️
⚠️ Original, no unauthorized reprint, only receive link reprint, do not accept content copy reprint!