以编程方式使用安全区域布局
因为我不使用故事板来创建我的视图,所以我想知道是否有编程的“使用安全区域指南”选项或类似的东西。以编程方式使用安全区域布局
我试图锚我的意见,以
view.safeAreaLayoutGuide
,但他们保持重叠在iPhone X模拟器的顶尖。
下面是示例代码(参考范围:Safe Area Layout Guide):
如果您创建约束代码中使用的UIView的safeAreaLayoutGuide属性来获取相关的布局锚。让我们重新上面的代码中Interface Builder的例子来看看它的外观:
假设我们有绿色的观点在我们的视图控制器属性:
private let greenView = UIView()
我们可能有一个函数来设置的意见和从viewDidLoad中称为约束:
private func setupView() {
greenView.translatesAutoresizingMaskIntoConstraints = false
greenView.backgroundColor = .green
view.addSubview(greenView)
}
一如既往使用根视图的layoutMarginsGuide创建的前缘和后缘的约束:
let margins = view.layoutMarginsGuide
NSLayoutConstraint.activate([
greenView.leadingAnchor.constraint(equalTo: margins.leadingAnchor),
greenView.trailingAnchor.constraint(equalTo: margins.trailingAnchor)
])
现在,除非你是针对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)
])
}
结果:
安全区苹果开发者官方文档需要处理的iPhone-X的用户界面设计。下面是How to design user interface for iPhone-X using Safe Area Layout
也可以在Objective-C中给出这个吗?它看起来就像我需要的东西 –
@TomHammond这里是在Objective-C为你https://stackoverflow.com/a/47076040/5638630 – Krunal
我们应该真的通过操作系统检查,而不是通过设备检查?我的意思是这个代码'#available(iOS 11,*)' –
我用这个来代替加前缘和后缘约束到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]
]];
也请您查看选项从Krunal的回答较低版本的IOS 11。
不工作......? – Nagarjun
确保您已将您的视图添加到superView中。这是self.view在我的代码中作为一个简单的例子。 –
SafeAreaLayoutGuide
是UIView
属性,
的safeAreaLayoutGuide的顶部指示视图的视野开阔顶部边缘 (例如,不背后 状态栏或导航栏,如果存在的话)。对于其他边缘也是如此。
使用safeAreaLayoutGuide
避免我们的对象从圆角,导航栏,选项卡栏,工具栏和其他祖先视图剪切/重叠。
我们可以分别创建safeAreaLayoutGuide
对象&设置对象约束。
约束的肖像+景观是 -
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
}
永远不要在'viewDidAppear'中设置约束,除非你完全知道你在做什么。 'viewDidAppear'被多次调用,所以每次调用时你的约束都会被复制。 –
是的! ,编辑答案,你可以用作你的用例。 – Jack
对于那些你们谁使用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()
}
}
是的,现在我的代码变大了3倍 –
实际上,我使用它的扩展和控制,如果它是IOS 11与否。
extension UIView {
var safeTopAnchor: NSLayoutYAxisAnchor {
if #available(iOS 11.0, *) {
return self.safeAreaLayoutGuide.topAnchor
} else {
return self.topAnchor
}
}
var safeLeftAnchor: NSLayoutXAxisAnchor {
if #available(iOS 11.0, *){
return self.safeAreaLayoutGuide.leftAnchor
}else {
return self.leftAnchor
}
}
var safeRightAnchor: NSLayoutXAxisAnchor {
if #available(iOS 11.0, *){
return self.safeAreaLayoutGuide.rightAnchor
}else {
return self.rightAnchor
}
}
var safeBottomAnchor: NSLayoutYAxisAnchor {
if #available(iOS 11.0, *) {
return self.safeAreaLayoutGuide.bottomAnchor
} else {
return self.bottomAnchor
}
}
}
不错,很酷的主意! – Phillip
以视觉格式使用约束,您可以免费获得对安全区域的尊重。
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))
}
}
没有记载布尔属性这个根据:https://developer.apple.com/documentation/uikit/uiview/positioning_content_relative_to_the_safe_area –
怎么样'view.safeAreaInsets'?你试过这个吗? –
@KarthikeyanBose是的,我很幸运没有运气。 – Phillip