Info | Value |
-------------------------|-------------------------------------|
Platform | e.g. ios
Platform Version | e.g. 11.0
SnapKit Version | e.g. 3.0.0
Integration Method | e.g. carthage/cocoapods/manually
iOS 11 introduced a new layout guide, Safe Area Layout Guide, which is meant to replace the top/bottom layout guides. This is required for the new iPhoneX
https://developer.apple.com/ios/human-interface-guidelines/overview/iphone-x/
This is possible already, though some documentation could be helpful. safeAreaLayoutGuide
is a UILayoutGuide
, which is already relatable in SnapKit via snp
. Example:
let subview = UIView()
addSubview(subview)
subview.snp.makeConstraints { make in
if #available(iOS 11, *) {
make.top.equalTo(safeAreaLayoutGuide.snp.topMargin)
} else {
make.top.equalTo(self)
}
}
@sprint84 @marclove is right here, you can already do this out of the box, and I don't think there's really a better way to do this because the safe area layout guides are on a view controller rather than a view and we don't extend view controller APIs
This is now in the docs, but I'm going to leave this issue open for awhile because it will prevent a bajillion new ones as people start to support safe layout areas.
As of Xcode 9 GM, safeAreaLayoutGuide
has been moved to UIView
's property.
@phamquochoan it's still a UILayoutGuide and an already accessible property. I suppose it could make sense to do something like .snp.safeArea
but it may be confusing of whether that is hitting the view controller or the view itself…
I just check the documentation of UIView
and UIViewController
, the safeAreaLayoutGuide
is removed from UIViewController
UIViewController
var additionalSafeAreaInsets: UIEdgeInsets
Custom insets that you specify to modify the view controller's safe area.
UIView
var safeAreaInsets: UIEdgeInsets
The insets that you use to determine the safe area for this view.
var safeAreaLayoutGuide: UILayoutGuide
The layout guide representing the portion of your view that is unobscured by bars and other content.
So if you could make .snp.safeArea
, it would be 💯
I've made an extension that you can use (XCode8/9 compatibility):
extension UIView {
var safeArea: ConstraintBasicAttributesDSL {
#if swift(>=3.2)
if #available(iOS 11.0, *) {
return self.safeAreaLayoutGuide.snp
}
return self.snp
#else
return self.snp
#endif
}
}
Usage example:
let subview = UIView()
addSubview(subview)
subview.snp.makeConstraints { make in
make.top.equalTo(self.safeArea.top)
}
@nunojfg - Thank you! For others consuming, don't forget to import SnapKit
so ConstraintBasicAttributesDSL
is defined. Cheers.
Will this extension give 20 as margin in top for statusbar when running pre ios11 @nunojfg ? Doesn't seem like it. Anyone has a suggestion for how to do that?
@jalmaas haven't tried since the app I'm developing doesn't have StatusBar, however it should work since I'm using safeAreaLayoutGuide for iOS11+ and no safeAreaLayoutGuide for iOS10-.
If it doesn't work the other solution is to use the height value from UIApplication.shared.statusBarFrame.size.height
How can I create a ConstraintBasicAttributesDSL with the statusbarframeheight to return?
Something like this?
let subview = UIView()
addSubview(subview)
subview.snp.makeConstraints { make in
make.top.equalTo(self.safeArea.top).offset(UIApplication.shared.statusBarFrame.size.height)
}
That would leave double statusbaroffset in ios 11? I was thinking more like this in the category (not working code):
extension UIView {
var safeArea: ConstraintBasicAttributesDSL {
#if swift(>=3.2)
if #available(iOS 11.0, *) {
return self.safeAreaLayoutGuide.snp
}
return LayoutGuide(createWithTopAnchor20).snp
#else
return LayoutGuide(createWithTopAnchor20).snp
#endif
}
}
Apple's recommendation for bottom-of-the-screen-full-width buttons is to add padding on sides (because it will be pushed up from the bottom by the safe area) -- but it isn't clear to me the preferred way to do that -- without using some kind of "is this iPhone X" conditional. Am I missing something?
make.leading.trailing.bottom.equalTo(self.additionalSafeAreaInsets.bottom)
iOS 11 & Onwards :
import SnapKit
extension UIView {
var safeArea : ConstraintLayoutGuideDSL {
return safeAreaLayoutGuide.snp
}
}
How to use:
containerView.snp.makeConstraints { (make) in
make.leading.trailing.equalToSuperview()
make.bottom.equalTo(view.safeArea.bottom)
}
Most helpful comment
This is possible already, though some documentation could be helpful.
safeAreaLayoutGuide
is aUILayoutGuide
, which is already relatable in SnapKit viasnp
. Example: