I try to set up a view with AutoLayout constraints by using constraintEqualToAnchor()
:
override func viewDidLoad() {
super.viewDidLoad()
le
Here is an example declaring a constraint c
which will be referenced later in time. We set a new constant value and then call layout
on the superview.
myView.translatesAutoresizingMaskIntoConstraints = false
var constraints: [NSLayoutConstraint] = [
myView.topAnchor.constraintEqualToAnchor(view.topAnchor),
myView.leftAnchor.constraintEqualToAnchor(view.leftAnchor),
myView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor)
]
let c = myView.rightAnchor.constraintEqualToAnchor(view.rightAnchor)
constraints.append(c)
view.addSubview(myView)
NSLayoutConstraint.activateConstraints(constraints)
// Some time later
c.constant = -100
view.setNeedsLayout()
// method myView.topAnchor.constraintEqualToAnchor creates new one inactive anchor
// and not returns exist with equal relationships
// you can set identifier for any constraint in Interface Builder or code and find & update in code
for ( NSLayoutConstraint *c in [self.view constraintsAffectingLayoutForAxis:UILayoutConstraintAxisHorizontal] )
{
if ( YES == [c.identifier isEqualToString:@"my.layout-constraint.id"] )
{
// Unlike the other properties, the constant can be modified
// after constraint creation.
// Setting the constant on an existing constraint performs much better
// than removing the constraint and adding a new one that's exactly like
// the old except that it has a different constant.
c.constant = 123;
// if needed
// [self.view setNeedsUpdateConstraints];
break;
}
}
You need to deactivate the previous constraint when activating a new one so that you don't end up over constraining your view. To do that, store a reference to each of the constraints as a property in your ViewController
and then set the active
property of the old constraint to false
before creating and activating the new constraint:
Swift 2.x:
class ViewController: UIViewController {
var leftConstraint: NSLayoutConstraint?
var trailingConstraint: NSLayoutConstraint?
var topConstraint: NSLayoutConstraint?
var bottomConstraint: NSLayoutConstraint?
override func viewDidLoad() {
super.viewDidLoad()
let myView = UIView()
myView.backgroundColor = UIColor.orangeColor()
myView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(myView)
leftConstraint = myView.leftAnchor.constraintEqualToAnchor(view.leftAnchor)
leftConstraint?.active = true
trailingConstraint = myView.trailingAnchor.constraintEqualToAnchor(view.trailingAnchor)
trailingConstraint?.active = true
topConstraint = myView.topAnchor.constraintEqualToAnchor(view.topAnchor)
topConstraint?.active = true
bottomConstraint = myView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor)
bottomConstraint?.active = true
/******************************************/
/* I try to change one of the constraints */
/******************************************/
leftConstraint?.active = false
leftConstraint = myView.leftAnchor.constraintEqualToAnchor(view.rightAnchor, constant: -100)
leftConstraint?.active = true
}
}
Update for Swift 3 syntax:
class ViewController: UIViewController {
var leftConstraint: NSLayoutConstraint?
var trailingConstraint: NSLayoutConstraint?
var topConstraint: NSLayoutConstraint?
var bottomConstraint: NSLayoutConstraint?
override func viewDidLoad() {
super.viewDidLoad()
let myView = UIView()
myView.backgroundColor = UIColor.orange
myView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(myView)
leftConstraint = myView.leftAnchor.constraint(equalTo: view.leftAnchor)
leftConstraint?.isActive = true
trailingConstraint = myView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
trailingConstraint?.isActive = true
topConstraint = myView.topAnchor.constraint(equalTo: view.topAnchor)
topConstraint?.isActive = true
bottomConstraint = myView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
bottomConstraint?.isActive = true
/******************************************/
/* I try to change one of the constraints */
/******************************************/
leftConstraint?.isActive = false
leftConstraint = myView.leftAnchor.constraint(equalTo: view.rightAnchor, constant: -100)
leftConstraint?.isActive = true
}
}
Here is example with if
statement modifying a StackView
and View
when a segmented clicked:
if (sender as AnyObject).selectedSegmentIndex == 0{
// Shrink the white view and stack view
heightConstraintView = containerView.heightAnchor.constraint(equalToConstant: 100)
heightConstraintView?.isActive = true
heightConstraintStackView = stackView.heightAnchor.constraint(equalToConstant: 100)
heightConstraintStackView?.isActive = true
} else {
// Before returning back the white view and stack view DEACTIVATE teh previous constraints
heightConstraintView?.isActive = false
heightConstraintStackView?.isActive = false
// Returning back the white view and stack view to normal size
heightConstraintView = containerView.heightAnchor.constraint(equalToConstant: 200)
heightConstraintView?.isActive = true
heightConstraintStackView = stackView.heightAnchor.constraint(equalToConstant: 200)
heightConstraintStackView?.isActive = true
}