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í: