lineales inecuaciones incognitas con como ios dynamic autolayout nslayoutconstraint

ios - incognitas - inecuaciones lineales



Ancho y alto ¿Igual a su supervista usando programación automática programáticamente? (10)

Enfoque n. ° 1: a través de la extensión UIView

Este es un enfoque más funcional en Swift 3+ con una precondición en lugar de una print (que puede desaparecer fácilmente en la consola). Éste informará los errores del programador como compilaciones fallidas.

Agregue esta extensión a su proyecto:

extension UIView { /// Adds constraints to the superview so that this view has same size and position. /// Note: This fails the build if the `superview` is `nil` – add it as a subview before calling this. func bindEdgesToSuperview() { guard let superview = superview else { preconditionFailure("`superview` was nil – call `addSubview(view: UIView)` before calling `bindEdgesToSuperview()` to fix this.") } translatesAutoresizingMaskIntoConstraints = false ["H:|-0-[subview]-0-|", "V:|-0-[subview]-0-|"].forEach { visualFormat in superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: visualFormat, options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self])) } } }

Ahora simplemente llámalo así:

// after adding as a subview, e.g. `view.addSubview(subview)` subview.bindEdgesToSuperview()

Tenga en cuenta que el método anterior ya está integrado en mi marco HandyUIKit que también agrega algunos más útiles ayudantes de UI en su proyecto.

Enfoque n. ° 2: uso de un marco

Si trabajas mucho con las restricciones programáticas de tu proyecto, te recomiendo que SnapKit . Hace que trabajar con restricciones sea mucho más fácil y menos propenso a errores .

Siga las instrucciones de instalación en los documentos para incluir SnapKit en su proyecto. Luego, impórtelo en la parte superior de su archivo Swift:

import SnapKit

Ahora puedes lograr lo mismo con solo esto:

subview.snp.makeConstraints { make in make.edges.equalToSuperview() }

He estado buscando muchos fragmentos en la red y todavía no puedo encontrar la respuesta a mi problema. Mi pregunta es que tengo un scrollView (SV) y quiero agregar un botón dentro de scrollView (SV) programáticamente con el mismo ancho y alto de su superview que es scrollView (SV) para que cuando el usuario gire el botón del dispositivo tendrá el mismo marco de scrollView (SV). cómo hacer el NSLayout / NSLayoutConstraint? Gracias


Como continuación de la solución de @Dschee, aquí está la sintaxis 3.0 rápida: (Tenga en cuenta: esta no es mi solución , la acabo de arreglar para Swift 3.0)

extension UIView { /// Adds constraints to this `UIView` instances `superview` object to make sure this always has the same size as the superview. /// Please note that this has no effect if its `superview` is `nil` – add this `UIView` instance as a subview before calling this. func bindFrameToSuperviewBounds() { guard let superview = self.superview else { print("Error! `superview` was nil – call `addSubview(view: UIView)` before calling `bindFrameToSuperviewBounds()` to fix this.") return } self.translatesAutoresizingMaskIntoConstraints = false superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self])) superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self])) }


Como una respuesta complementaria, y una para aquellos que no se oponen a incluir bibliotecas de terceros, la biblioteca PureLayout proporciona un método para hacer esto. Una vez que la biblioteca está instalada, es tan simple como

myView.autoPinEdgesToSuperviewEdges()

Existen otras bibliotecas que también pueden proporcionar una funcionalidad similar en función del gusto, p. Ej. Masonry , Cartography .


Este enlace puede ayudarlo, siga las instrucciones: http://www.raywenderlich.com/20881/beginning-auto-layout-part-1-of-2

EDITAR:

use el siguiente fragmento de código, donde la subvista es su subivew.

[subview setTranslatesAutoresizingMaskIntoConstraints:NO]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[subview]-0-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(subview)]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[subview]-0-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(subview)]];


Necesitaba cubrir la supervista por completo. Los otros no harían eso durante los cambios de orientación. Así que escribí uno nuevo que sí lo hace, usando un multiplicador de tamaño arbitrario de 20. Siéntase libre de cambiar a sus necesidades. También tenga en cuenta que este hecho hace que la subvista sea mucho más grande que la supervista, que podría ser diferente de los requisitos.

extension UIView { func coverSuperview() { guard let superview = self.superview else { assert(false, "Error! `superview` was nil – call `addSubview(_ view: UIView)` before calling `/(#function)` to fix this.") return } self.translatesAutoresizingMaskIntoConstraints = false let multiplier = CGFloat(20.0) NSLayoutConstraint.activate([ self.heightAnchor.constraint(equalTo: superview.heightAnchor, multiplier: multiplier), self.widthAnchor.constraint(equalTo: superview.widthAnchor, multiplier: multiplier), self.centerXAnchor.constraint(equalTo: superview.centerXAnchor), self.centerYAnchor.constraint(equalTo: superview.centerYAnchor), ]) } }


No estoy seguro de si esta es la forma más eficiente de hacerlo, pero funciona ...

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.translatesAutoresizingMaskIntoConstraints = NO; // initialize [coverForScrolView addSubview:button]; NSLayoutConstraint *width =[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeWidth relatedBy:0 toItem:coverForScrolView attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0]; NSLayoutConstraint *height =[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeHeight relatedBy:0 toItem:coverForScrolView attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0]; NSLayoutConstraint *top = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:coverForScrolView attribute:NSLayoutAttributeTop multiplier:1.0f constant:0.f]; NSLayoutConstraint *leading = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:coverForScrolView attribute:NSLayoutAttributeLeading multiplier:1.0f constant:0.f]; [coverForScrolView addConstraint:width]; [coverForScrolView addConstraint:height]; [coverForScrolView addConstraint:top]; [coverForScrolView addConstraint:leading];


Swift 3:

import UIKit extension UIView { func bindFrameToSuperviewBounds() { guard let superview = self.superview else { print("Error! `superview` was nil – call `addSubview(view: UIView)` before calling `bindFrameToSuperviewBounds()` to fix this.") return } self.translatesAutoresizingMaskIntoConstraints = false superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self])) superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self])) } }


addConstraint métodos addConstraint y removeConstraint para UIView van a estar en desuso, por lo que vale la pena utilizar ''conveniencias de creación de restricciones'':

view.topAnchor.constraint(equalTo: superView.topAnchor, constant: 0).isActive = true view.bottomAnchor.constraint(equalTo: superView.bottomAnchor, constant: 0).isActive = true view.leadingAnchor.constraint(equalTo: superView.leadingAnchor, constant: 0).isActive = true view.trailingAnchor.constraint(equalTo: superView.trailingAnchor, constant: 0).isActive = true


Swift 4 usando NSLayoutConstraint :

footerBoardImageView.translatesAutoresizingMaskIntoConstraints = false let widthConstraint = NSLayoutConstraint(item: yourview, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: superview, attribute: NSLayoutAttribute.width, multiplier: 1, constant: 0) let heightConstraint = NSLayoutConstraint(item: yourview, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: superview, attribute: NSLayoutAttribute.height, multiplier: 1, constant: 0) superview.addConstraints([widthConstraint, heightConstraint])


Si alguien está buscando una solución Swift , crearía una extensión Swift para UIView que le ayudará cada vez que quiera vincular un marco de subvistas a sus límites de superviews:

Swift 2:

extension UIView { /// Adds constraints to this `UIView` instances `superview` object to make sure this always has the same size as the superview. /// Please note that this has no effect if its `superview` is `nil` – add this `UIView` instance as a subview before calling this. func bindFrameToSuperviewBounds() { guard let superview = self.superview else { print("Error! `superview` was nil – call `addSubview(view: UIView)` before calling `bindFrameToSuperviewBounds()` to fix this.") return } self.translatesAutoresizingMaskIntoConstraints = false superview.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[subview]-0-|", options: .DirectionLeadingToTrailing, metrics: nil, views: ["subview": self])) superview.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[subview]-0-|", options: .DirectionLeadingToTrailing, metrics: nil, views: ["subview": self])) } }

Swift 3:

extension UIView { /// Adds constraints to this `UIView` instances `superview` object to make sure this always has the same size as the superview. /// Please note that this has no effect if its `superview` is `nil` – add this `UIView` instance as a subview before calling this. func bindFrameToSuperviewBounds() { guard let superview = self.superview else { print("Error! `superview` was nil – call `addSubview(view: UIView)` before calling `bindFrameToSuperviewBounds()` to fix this.") return } self.translatesAutoresizingMaskIntoConstraints = false superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self])) superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self])) } }

Entonces simplemente llámalo así :

// after adding as a subview, e.g. `view.addSubview(subview)` subview.bindFrameToSuperviewBounds()