wake-up-neo.com

Verwenden Sie das Safe Area Layout programmgesteuert

Da ich keine Storyboards zum Erstellen meiner Ansichten verwende, habe ich mich gefragt, ob es die programmgesteuerte Option "Use Safe Area Guides" gibt. 

Ich habe versucht, meine Ansichten zu verankern 

view.safeAreaLayoutGuide

im iPhone X-Simulator überlappen sie jedoch weiterhin die Oberklasse.

59
Phillip

Hier ist Beispielcode (Ref:: Safe Area Layout Guide ):
Wenn Sie Ihre Einschränkungen im Code erstellen, verwenden Sie die Eigenschaft safeAreaLayoutGuide von UIView, um die entsprechenden Layoutanker abzurufen. Lassen Sie uns das obige Interface Builder-Beispiel im Code neu erstellen, um zu sehen, wie es aussieht:

Angenommen, wir haben die grüne Ansicht als Eigenschaft in unserem Ansichtscontroller:

private let greenView = UIView()

Möglicherweise verfügen wir über eine Funktion zum Einrichten der von viewDidLoad aufgerufenen Ansichten und Einschränkungen:

private func setupView() {
  greenView.translatesAutoresizingMaskIntoConstraints = false
  greenView.backgroundColor = .green
  view.addSubview(greenView)
}

Erstellen Sie die Beschränkungen für den vorderen und den nachlaufenden Rand wie immer mithilfe des layoutMarginsGuide der Stammansicht:

 let margins = view.layoutMarginsGuide
    NSLayoutConstraint.activate([
      greenView.leadingAnchor.constraint(equalTo: margins.leadingAnchor),
      greenView.trailingAnchor.constraint(equalTo: margins.trailingAnchor)
 ])

Wenn Sie nun auf iOS 11 und höher abzielen, müssen Sie die Einschränkungen für die Layout-Richtlinien für den sicheren Bereich mit #available umschließen und in den oberen und unteren Layout-Anleitungen für frühere iOS-Versionen zurückgreifen:

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)
   ])
}

Ergebnis:

enter image description here

enter image description here


Hier ist die offizielle Dokumentation für Apple Developer für Safe Area Layout Guide


Safe Area ist erforderlich, um das Design der Benutzeroberfläche für das iPhone-X zu verwalten. Hier ist eine grundlegende Richtlinie für Wie gestaltet man die Benutzeroberfläche für das iPhone-X mit Safe Area Layout

92
Krunal

Ich verwende tatsächlich eine Erweiterung dafür und kontrolliere, ob es sich um iOS 11 handelt oder nicht.

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
    }
  }
}
51
Alper

SafeAreaLayoutGuide ist UIView-Eigenschaft, 

Die Oberseite des safeAreaLayoutGuide zeigt den nicht gesicherten oberen Rand an der Ansicht (z. B. nicht hinter .__ der Statusleiste oder Navigationsleiste, falls vorhanden). Ähnlich für die anderen Kanten.

Verwenden Sie safeAreaLayoutGuide, um zu vermeiden, dass sich Objekte aus abgerundeten Ecken, Navigationsleisten, Registerkartenleisten, Symbolleisten und anderen Vorfahrenansichten schneiden.

Wir können safeAreaLayoutGuide-Objekte erstellen und Objekteinschränkungen festlegen.

Einschränkungen für Porträt + Landschaft sind -

 Portrait image

 Landscape image

        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
        }

UILayoutGuide

safeAreaLayoutGuide

9
Jack

Für diejenigen von Ihnen, die SnapKit verwenden, ist die Lösung, genau wie ich, die Lösung, Ihre Einschränkungen an view.safeAreaLayoutGuide zu verankern:

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()
     }
}
8
Phillip

Ich benutze dies, anstatt dem layoutMarginsGuide die Rand- und Nachlaufeinschränkungen hinzuzufügen:

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]
                                          ]];

Bitte überprüfen Sie auch die Option für eine niedrigere Version von iOS 11 aus der Antwort von Krunal.

7
Tony TRAN

Verwenden Sie UIWindow oder UIViews 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]
5

Verwenden Sie Einschränkungen mit dem visuellen Format, und Sie erhalten kostenlos Respekt für den sicheren Bereich. 

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))
    }
}

 result

3
Chris Woolfe

Sichere Bereicherweiterung Für 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
3
black_pearl

Swift 4.2 und 5.0. Angenommen, Sie möchten in viewBg Leading-, Trailing-, Top- und Bottom-Einschränkungen hinzufügen. Sie können also den folgenden Code verwenden.

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
0
GSK

Sie können view.safeAreaInsets wie hier erklärt verwenden https://www.raywenderlich.com/174078/auto-layout-visual-format-language-tutorial-2

codebeispiel (von raywenderlich.com übernommen):

override func viewSafeAreaInsetsDidChange() {
  super.viewSafeAreaInsetsDidChange()

  if !allConstraints.isEmpty {
    NSLayoutConstraint.deactivate(allConstraints)
    allConstraints.removeAll()
  }

  let newInsets = view.safeAreaInsets
  let leftMargin = newInsets.left > 0 ? newInsets.left : Metrics.padding
  let rightMargin = newInsets.right > 0 ? newInsets.right : Metrics.padding
  let topMargin = newInsets.top > 0 ? newInsets.top : Metrics.padding
  let bottomMargin = newInsets.bottom > 0 ? newInsets.bottom : Metrics.padding

  let metrics = [
    "horizontalPadding": Metrics.padding,
    "iconImageViewWidth": Metrics.iconImageViewWidth,
    "topMargin": topMargin,
    "bottomMargin": bottomMargin,
    "leftMargin": leftMargin,
    "rightMargin": rightMargin]
}


let views: [String: Any] = [
  "iconImageView": iconImageView,
  "appNameLabel": appNameLabel,
  "skipButton": skipButton,
  "appImageView": appImageView,
  "welcomeLabel": welcomeLabel,
  "summaryLabel": summaryLabel,
  "pageControl": pageControl]

let iconVerticalConstraints = NSLayoutConstraint.constraints(
  withVisualFormat: "V:|-topMargin-[iconImageView(30)]",
  metrics: metrics,
  views: views)
allConstraints += iconVerticalConstraints

let topRowHorizontalFormat = """
  H:|-leftMargin-[iconImageView(iconImageViewWidth)]-[appNameLabel]-[skipButton]-rightMargin-|
  """
...
0
Serg