what safe how guides guide ios swift iphone-x safearealayoutguide

ios - safe - Utilice el diseño de área segura mediante programación



xcode 9 safe area (10)

Aquí hay un código de muestra (Ref: Guía de diseño de área segura ):
Si crea sus restricciones en el código, use la propiedad safeAreaLayoutGuide de UIView para obtener los anclajes de diseño relevantes. Recreemos el ejemplo anterior de Interface Builder en código para ver cómo se ve:

Suponiendo que tenemos la vista verde como una propiedad en nuestro controlador de vista:

private let greenView = UIView()

Podríamos tener una función para configurar las vistas y restricciones llamadas desde viewDidLoad:

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

Cree las restricciones de margen inicial y final como siempre utilizando el layoutMarginsGuide de la vista raíz:

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

Ahora, a menos que esté apuntando a iOS 11 y versiones posteriores, deberá ajustar las restricciones de la guía de diseño de área segura con #available y recurrir a las guías de diseño superior e inferior para versiones anteriores de 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) ]) }

Resultado:


Aquí está la documentación oficial del desarrollador de Apple para la guía de diseño de área segura


Se requiere un área segura para manejar el diseño de la interfaz de usuario para iPhone-X. Aquí hay una guía básica sobre cómo diseñar una interfaz de usuario para iPhone-X usando el diseño de área segura

Como no uso guiones gráficos para crear mis vistas, me preguntaba si existe la opción "Usar guías de área segura" mediante programación o algo así.

He tratado de anclar mis puntos de vista a

view.safeAreaLayoutGuide

pero siguen superponiéndose a la muesca superior en el simulador de iPhone X.


De hecho, estoy usando una extensión y controlo si es ios 11 o no.

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


Estoy usando esto en lugar de agregar restricciones de margen iniciales y finales al 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] ]];

Por favor, marque también la opción para la versión inferior de iOS 11 de la respuesta de Krunal.


Extensión de área segura para 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


Para aquellos de ustedes que usan SnapKit , al igual que yo, la solución es anclar sus restricciones para view.safeAreaLayoutGuide manera:

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


Puede usar view.safeAreaInsets como se explica aquí https://www.raywenderlich.com/174078/auto-layout-visual-format-language-tutorial-2

código de muestra (tomado de raywenderlich.com):

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-| """ ...


Swift 4.2 y 5.0. Suponga que desea agregar restricciones iniciales, finales, superiores e inferiores en viewBg. Entonces, puedes usar el siguiente código.

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


Use UIWindow o UIView ''s 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]


Use restricciones con formato visual y obtendrá respeto por el área segura de forma gratuita.

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


SafeAreaLayoutGuide es propiedad de UIView ,

La parte superior de safeAreaLayoutGuide indica el borde superior despejado de la vista (por ejemplo, no detrás de la barra de estado o la barra de navegación, si está presente). Del mismo modo para los otros bordes.

Utilice safeAreaLayoutGuide para evitar que nuestros objetos se safeAreaLayoutGuide / superpongan desde esquinas redondeadas, barras de navegación, barras de pestañas, barras de herramientas y otras vistas de antepasados.

Podemos crear safeAreaLayoutGuide objeto safeAreaLayoutGuide y establecer restricciones de objeto respectivamente.

Restricciones para Retrato + Paisaje es -

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