ios objective-c swift autolayout nslayoutconstraint

ios - Actualizar la restricción de altura mediante programación



nslayoutconstraint swift 4 (5)

Soy nuevo en diseño automático. He hecho todo mi proyecto desde el archivo xib, pero ahora me enfrento a un problema en el que tengo que actualizar la altura de una vista mediante programación. Lo he intentado a continuación pero ahora estoy trabajando.

[[self view] addConstraint:[NSLayoutConstraint constraintWithItem:loginContainer attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:loginFrame.size.height]];

En la consola se muestra

Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don''t want. Try this: (1) look at each constraint and try to figure out which you don''t expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you''re seeing NSAutoresizingMaskLayoutConstraints that you don''t understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) ( "<NSLayoutConstraint:0x78724530 V:[UIView:0x790cdfb0(170)]>", "<NSLayoutConstraint:0x787da210 V:[UIView:0x790cdfb0(400)]>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x78724530 V:[UIView:0x790cdfb0(170)]> Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.


En lugar de agregar una nueva restricción, debe modificar la constante en su restricción existente.

Use un IBOutlet para conectarse a su restricción en Interface Builder:

@property (nonatomic, weak) NSLayoutConstraint *heightConstraint;

Luego, cuando necesite configurarlo mediante programación, simplemente configure la propiedad constante en la restricción:

heightConstraint.constant = 100;

O

Si no puede acceder a la punta en Interface Builder, encuentre la restricción en el código:

NSLayoutConstraint *heightConstraint; for (NSLayoutConstraint *constraint in myView.constraints) { if (constraint.firstAttribute == NSLayoutAttributeHeight) { heightConstraint = constraint; break; } } heightConstraint.constant = 100;

Y en Swift:

if let constraint = (myView.constraints.filter{$0.firstAttribute == .width}.first) { constraint.constant = 100.0 }


Llamemos a su vista nibView. Entonces, está tratando de cargar esa vista en un controlador de vista, así que primero, en su controlador de vista, debe cargarla mientras lo hace con:

[[NSBundle mainBundle] loadNibNamed:@"NibView" owner:self options:nil];

Luego, debe decirle a nibView que no lo necesita para transformar las máscaras de autoresizing en restricciones haciendo

nibView.translatesAutoresizingMaskIntoConstraints = NO;

Luego, puede agregar sus restricciones

NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem:nibView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:yourValue];

Y finalmente solo agrégalo a las restricciones de tu vista:

[self.view addConstraint:heightConstraint];

Probablemente también deba agregar una restricción de ancho.


Para obtener una referencia de sus restricciones de altura: Haga clic + Ctrl en la restricción y arrastre y suelte en su archivo de clase:

Para actualizar el valor de restricción:

self.heightConstraint.constant = 300; [self.view updateConstraints];


Una forma más flexible usando esta extensión rápida:

extension UIView { func updateConstraint(attribute: NSLayoutAttribute, constant: CGFloat) -> Void { if let constraint = (self.constraints.filter{$0.firstAttribute == attribute}.first) { constraint.constant = constant self.layoutIfNeeded() } } }

Cómo usar esta extensión de vista para actualizar el valor constante de las restricciones existentes:

// to update height constant testView.updateConstraint(attribute: NSLayoutAttribute.height, constant: 20.0) // to update width constant testView.updateConstraint(attribute: NSLayoutAttribute.width, constant: 20.0)


Swift 4.2

Uso de diseño automático y animación para aumentar la altura del botón

No uso el storyboard. Todas las cosas en código.

import UIKit class AnimateHeightConstraintViewController: UIViewController { var flowHeightConstraint: NSLayoutConstraint? override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white view.addSubview(button) button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true button.widthAnchor.constraint(equalToConstant: 100).isActive = true flowHeightConstraint = button.heightAnchor.constraint(equalToConstant: 30) flowHeightConstraint?.isActive = true } @objc func animateButtonTapped() { UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseOut, animations: { self.flowHeightConstraint?.constant = 100 self.view.layoutIfNeeded() }, completion: nil) } lazy var button: UIButton = { let button = UIButton() button.translatesAutoresizingMaskIntoConstraints = false button.backgroundColor = .green button.addTarget(self, action: #selector(animateButtonTapped), for: .touchUpInside) return button }() }

y el resultado es así: