ios 如何以编程方式使用安全区域布局?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/46317061/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I use Safe Area Layout programmatically?
提问by Phillip
Since I don't use storyboards to create my views, I was wondering if there's the "Use Safe Area Guides" option programmatically or something like that.
由于我不使用故事板来创建我的视图,我想知道是否有“使用安全区域指南”选项以编程方式或类似的方式。
I've tried to anchor my views to
我试图将我的观点锚定在
view.safeAreaLayoutGuide
view.safeAreaLayoutGuide
but they keep overlapping the top notch in the iPhone X simulator.
但它们在 iPhone X 模拟器中一直处于领先地位。
回答by Krunal
Here is sample code (Ref from: Safe Area Layout Guide):
If you create your constraints in code use the safeAreaLayoutGuide property of UIView to get the relevant layout anchors. Let's recreate the above Interface Builder example in code to see how it looks:
这是示例代码(参考:安全区域布局指南):
如果您在代码中创建约束,请使用 UIView 的 safeAreaLayoutGuide 属性来获取相关的布局锚点。让我们在代码中重新创建上面的 Interface Builder 示例,看看它的外观:
Assuming we have the green view as a property in our view controller:
假设我们的视图控制器中有绿色视图作为属性:
private let greenView = UIView()
We might have a function to set up the views and constraints called from viewDidLoad:
我们可能有一个函数来设置从 viewDidLoad 调用的视图和约束:
private func setupView() {
greenView.translatesAutoresizingMaskIntoConstraints = false
greenView.backgroundColor = .green
view.addSubview(greenView)
}
Create the leading and trailing margin constraints as always using the layoutMarginsGuide of the root view:
像往常一样使用根视图的 layoutMarginsGuide 创建前导和尾随边距约束:
let margins = view.layoutMarginsGuide
NSLayoutConstraint.activate([
greenView.leadingAnchor.constraint(equalTo: margins.leadingAnchor),
greenView.trailingAnchor.constraint(equalTo: margins.trailingAnchor)
])
Now, unless you are targeting iOS 11 and later, you will need to wrap the safe area layout guide constraints with #available and fall back to top and bottom layout guides for earlier iOS versions:
现在,除非您的目标是 iOS 11 及更高版本,否则您需要使用 #available 包装安全区域布局指南约束,并回退到早期 iOS 版本的顶部和底部布局指南:
if #available(iOS 11, *) {
let guide = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
greenView.topAnchor.constraintEqualToSystemSpacingBelow(guide.topAnchor, multiplier: 1.0),
guide.bottomAnchor.constraintEqualToSystemSpacingBelow(greenView.bottomAnchor, multiplier: 1.0)
])
} else {
let standardSpacing: CGFloat = 8.0
NSLayoutConstraint.activate([
greenView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor, constant: standardSpacing),
bottomLayoutGuide.topAnchor.constraint(equalTo: greenView.bottomAnchor, constant: standardSpacing)
])
}
Result:
结果:
Here is Apple Developer Official Documentation for Safe Area Layout Guide
这是安全区域布局指南的Apple Developer 官方文档
Safe Area is required to handle user interface design for iPhone-X. Here is basic guideline for How to design user interface for iPhone-X using Safe Area Layout
需要 Safe Area 来处理 iPhone-X 的用户界面设计。这是如何使用安全区域布局为 iPhone-X 设计用户界面的基本指南
回答by Alper
I'm actually using an extension for it and controlling if it is ios 11 or not.
我实际上正在使用它的扩展并控制它是否是 ios 11。
extension UIView {
var safeTopAnchor: NSLayoutYAxisAnchor {
if #available(iOS 11.0, *) {
return self.safeAreaLayoutGuide.topAnchor
}
return self.topAnchor
}
var safeLeftAnchor: NSLayoutXAxisAnchor {
if #available(iOS 11.0, *){
return self.safeAreaLayoutGuide.leftAnchor
}
return self.leftAnchor
}
var safeRightAnchor: NSLayoutXAxisAnchor {
if #available(iOS 11.0, *){
return self.safeAreaLayoutGuide.rightAnchor
}
return self.rightAnchor
}
var safeBottomAnchor: NSLayoutYAxisAnchor {
if #available(iOS 11.0, *) {
return self.safeAreaLayoutGuide.bottomAnchor
}
return self.bottomAnchor
}
}
回答by Hyman
SafeAreaLayoutGuide
is UIView
property,
SafeAreaLayoutGuide
是UIView
财产,
The top of the safeAreaLayoutGuide indicates the unobscured top edge of the view (e.g, not behind the status bar or navigation bar, if present). Similarly for the other edges.
safeAreaLayoutGuide 的顶部表示视图未被遮挡的顶部边缘(例如,不在状态栏或导航栏后面,如果有的话)。其他边也类似。
Use safeAreaLayoutGuide
for avoid our objects clipping/overlapping from rounded corners, navigation bars, tab bars, toolbars, and other ancestor views.
使用safeAreaLayoutGuide
为避免我们的对象裁剪/从圆角,导航栏,标签栏,工具栏和其他祖先意见重叠。
We can create safeAreaLayoutGuide
object & set object constraints respectively.
我们可以分别创建safeAreaLayoutGuide
对象和设置对象约束。
Constraints for Portrait + Landscape is -
肖像 + 风景的约束是 -
self.edgesForExtendedLayout = []//Optional our as per your view ladder
let newView = UIView()
newView.backgroundColor = .red
self.view.addSubview(newView)
newView.translatesAutoresizingMaskIntoConstraints = false
if #available(iOS 11.0, *) {
let guide = self.view.safeAreaLayoutGuide
newView.trailingAnchor.constraint(equalTo: guide.trailingAnchor).isActive = true
newView.leadingAnchor.constraint(equalTo: guide.leadingAnchor).isActive = true
newView.topAnchor.constraint(equalTo: guide.topAnchor).isActive = true
newView.heightAnchor.constraint(equalToConstant: 100).isActive = true
}
else {
NSLayoutConstraint(item: newView, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1.0, constant: 0).isActive = true
NSLayoutConstraint(item: newView, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1.0, constant: 0).isActive = true
NSLayoutConstraint(item: newView, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1.0, constant: 0).isActive = true
newView.heightAnchor.constraint(equalToConstant: 100).isActive = true
}
回答by Phillip
For those of you who use SnapKit, just like me, the solution is anchoring your constraints to view.safeAreaLayoutGuide
like so:
对于那些使用SnapKit 的人,就像我一样,解决方案是将您的约束锚定为view.safeAreaLayoutGuide
这样:
yourView.snp.makeConstraints { (make) in
if #available(iOS 11.0, *) {
//Bottom guide
make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottomMargin)
//Top guide
make.top.equalTo(view.safeAreaLayoutGuide.snp.topMargin)
//Leading guide
make.leading.equalTo(view.safeAreaLayoutGuide.snp.leadingMargin)
//Trailing guide
make.trailing.equalTo(view.safeAreaLayoutGuide.snp.trailingMargin)
} else {
make.edges.equalToSuperview()
}
}
回答by Tony TRAN
I'm using this instead of add leading and trailing margin constraints to the layoutMarginsGuide:
我正在使用它而不是向 layoutMarginsGuide 添加前导和尾随边距约束:
UILayoutGuide *safe = self.view.safeAreaLayoutGuide;
yourView.translatesAutoresizingMaskIntoConstraints = NO;
[NSLayoutConstraint activateConstraints:@[
[safe.trailingAnchor constraintEqualToAnchor:yourView.trailingAnchor],
[yourView.leadingAnchor constraintEqualToAnchor:safe.leadingAnchor],
[yourView.topAnchor constraintEqualToAnchor:safe.topAnchor],
[safe.bottomAnchor constraintEqualToAnchor:yourView.bottomAnchor]
]];
Please also check the option for lower version of ios 11 from Krunal's answer.
另请从 Krunal 的回答中检查较低版本的 ios 11 选项。
回答by Warif Akhand Rishi
Use UIWindow
or UIView
's safeAreaInsets
.bottom
.top
.left
.right
使用UIWindow
或UIView
的safeAreaInsets
.bottom
.top
.left
.right
// #available(iOS 11.0, *)
// height - UIApplication.shared.keyWindow!.safeAreaInsets.bottom
// On iPhoneX
// UIApplication.shared.keyWindow!.safeAreaInsets.top = 44
// UIApplication.shared.keyWindow!.safeAreaInsets.bottom = 34
// Other devices
// UIApplication.shared.keyWindow!.safeAreaInsets.top = 0
// UIApplication.shared.keyWindow!.safeAreaInsets.bottom = 0
// example
let window = UIApplication.shared.keyWindow!
let viewWidth = window.frame.size.width
let viewHeight = window.frame.size.height - window.safeAreaInsets.bottom
let viewFrame = CGRect(x: 0, y: 0, width: viewWidth, height: viewHeight)
let aView = UIView(frame: viewFrame)
aView.backgroundColor = .red
view.addSubview(aView)
aView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
回答by AtomicBoolean
Use constraints with visual format and you get respect for the safe area for free.
使用具有视觉格式的约束,您将免费获得对安全区域的尊重。
class ViewController: UIViewController {
var greenView = UIView()
override func viewDidLoad() {
super.viewDidLoad()
greenView.backgroundColor = .green
view.addSubview(greenView)
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
greenView.translatesAutoresizingMaskIntoConstraints = false
let views : [String:Any] = ["greenView":greenView]
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-[greenView]-|", options: [], metrics: nil, views: views))
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-[greenView]-|", options: [], metrics: nil, views: views))
}
}
回答by black_pearl
Safe area extension For Objective-C
Objective-C的安全区域扩展
@implementation UIView (SafeArea)
- (NSLayoutAnchor *)safeTopAnchor{
if (@available(iOS 11.0, *)){
return self.safeAreaLayoutGuide.topAnchor;
} else {
return self.topAnchor;
}
}
- (NSLayoutAnchor *)safeBottomAnchor{
if (@available(iOS 11.0, *)) {
return self.safeAreaLayoutGuide.bottomAnchor;
} else {
return self.bottomAnchor;
}
}
@end
回答by Gurjinder Singh
Swift 4.2 and 5.0. Suppose you wan to add Leading, Trailing, Top and Bottom constraints on viewBg. So, you can use the below code.
斯威夫特 4.2 和 5.0。假设您想在 viewBg 上添加前导、尾随、顶部和底部约束。因此,您可以使用以下代码。
let guide = self.view.safeAreaLayoutGuide
viewBg.trailingAnchor.constraint(equalTo: guide.trailingAnchor).isActive = true
viewBg.leadingAnchor.constraint(equalTo: guide.leadingAnchor).isActive = true
viewBg.topAnchor.constraint(equalTo: guide.topAnchor).isActive = true
viewBg.bottomAnchor.constraint(equalTo: guide.bottomAnchor).isActive = true
回答by Reimond Hill
This extension helps you to constraint a UIVIew to its superview and superview+safeArea:
这个扩展可以帮助你将 UIVIew 约束到它的 superview 和 superview+safeArea:
extension UIView {
///Constraints a view to its superview
func constraintToSuperView() {
guard let superview = superview else { return }
translatesAutoresizingMaskIntoConstraints = false
topAnchor.constraint(equalTo: superview.topAnchor).isActive = true
leftAnchor.constraint(equalTo: superview.leftAnchor).isActive = true
bottomAnchor.constraint(equalTo: superview.bottomAnchor).isActive = true
rightAnchor.constraint(equalTo: superview.rightAnchor).isActive = true
}
///Constraints a view to its superview safe area
func constraintToSafeArea() {
guard let superview = superview else { return }
translatesAutoresizingMaskIntoConstraints = false
topAnchor.constraint(equalTo: superview.safeAreaLayoutGuide.topAnchor).isActive = true
leftAnchor.constraint(equalTo: superview.safeAreaLayoutGuide.leftAnchor).isActive = true
bottomAnchor.constraint(equalTo: superview.safeAreaLayoutGuide.bottomAnchor).isActive = true
rightAnchor.constraint(equalTo: superview.safeAreaLayoutGuide.rightAnchor).isActive = true
}
}