以编程方式使用安全区域布局

Phi*_*lip 83 ios swift safearealayoutguide iphone-x

由于我不使用故事板来创建我的视图,我想知道是否有编程方式的"使用安全区域指南"选项或类似的东西.

我试图将我的观点固定在

view.safeAreaLayoutGuide

但它们仍然与iPhone X模拟器中的顶级重叠.

Kru*_*nal 118

下面是示例代码(参考:安全区域布局指南):
如果在代码中创建约束,请使用UIView的safeAreaLayoutGuide属性来获取相关的布局锚点.让我们在代码中重新创建上面的Interface Builder示例,看看它的外观:

假设我们在视图控制器中将绿色视图作为属性:

private let greenView = UIView()
Run Code Online (Sandbox Code Playgroud)

我们可能有一个函数来设置从viewDidLoad调用的视图和约束:

private func setupView() {
  greenView.translatesAutoresizingMaskIntoConstraints = false
  greenView.backgroundColor = .green
  view.addSubview(greenView)
}
Run Code Online (Sandbox Code Playgroud)

使用根视图的layoutMarginsGuide始终创建前导和尾随边距约束:

 let margins = view.layoutMarginsGuide
 NSLayoutConstraint.activate([
    greenView.leadingAnchor.constraint(equalTo: margins.leadingAnchor),
    greenView.trailingAnchor.constraint(equalTo: margins.trailingAnchor)
 ])
Run Code Online (Sandbox Code Playgroud)

现在,除非您的目标是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)
   ])
}
Run Code Online (Sandbox Code Playgroud)

结果:

在此输入图像描述

在此输入图像描述


以下是Apple Developer官方文档的安全区域布局指南


需要安全区域来处理iPhone-X的用户界面设计.以下是如何使用安全区域布局为iPhone-X设计用户界面的基本准则

  • @TomHammond这是针对你的Objective-C /sf/answers/3295322831/ (6认同)
  • 真棒.谢谢 :) (3认同)
  • 是否有可能以客观C为目标?它看起来就像我需要的 (2认同)
  • @ZonilyJame现在关于你的查询 - SaFeAreaLayout是iOS特定的框架(不是特定于iPhoneX的设备),它正在取代iOS 11中的Top-Bottom Layout指南,因此我们必须使用/设置iOS条件而不是设备.SafeAreaLayout负责所有类型设备(iPhone-X和其他设备)的设计.如果您仍有疑问/疑惑,可以向我询问更多详情. (2认同)

Alp*_*per 67

我实际上正在使用它的扩展并控制它是否是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
  }
}
Run Code Online (Sandbox Code Playgroud)


Jac*_*ack 15

SafeAreaLayoutGuideUIView财产,

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
        }
Run Code Online (Sandbox Code Playgroud)

UILayoutGuide

safeAreaLayoutGuide

  • 除非你完全知道自己在做什么,否则永远不要在`viewDidAppear`中进行设置约束.`viewDidAppear`被多次调用,因此,每次调用时,您的约束都会被复制. (2认同)

Phi*_*lip 11

对于那些使用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()
     }
}
Run Code Online (Sandbox Code Playgroud)


Gur*_*ngh 9

斯威夫特 4.2 和 5.0。假设您要在viewBg上添加leadingtrailingtopbottom约束。因此,您可以使用下面的代码。

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
Run Code Online (Sandbox Code Playgroud)


Ton*_*RAN 6

我正在使用它而不是向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]
                                          ]];
Run Code Online (Sandbox Code Playgroud)

还请从Krunal的答案中查看较低版本ios 11的选项.


War*_*shi 6

使用UIWindowUIView'ssafeAreaInsets .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]
Run Code Online (Sandbox Code Playgroud)

  • 如果您的视图未使用AutoLayout,则可以使用此方法. (3认同)