[iOS] Dynamic Change AutoLayout’s NSConstraint

Zippy Calculator‘s Japanese user wrote review.

It’s more easier to use if calculate buttons and history area position are swapped.

Zippy Calculator’s layout is horizontal layout now.
I added new feature that can swap those position. I submitted new version to App Store. If they approve the app smoothly, it will update next week.


This post is how to implement this feature.

Finished Project

I made a new project to explain.


Push below button, then swap left and right position of the views.

dynamic_autolayout1 dynamic_autolayout2

There are three NSConstraints in the view. Left, right and center.


Add another three NSConstraint for swapped layout, and uncheck installed in Interface Builder.


The uninstalled NSConstraint are displayed with gray color.



You finished opration in Interface Builder. Next, write a code.

import UIKit

class ViewController: UIViewController {
    //for Layout 1
    @IBOutlet weak var yellowLeadingConstraint: NSLayoutConstraint!
    @IBOutlet weak var yellowTrailingBlueLeadingConstraint: NSLayoutConstraint!
    @IBOutlet weak var blueTrailingConstraint: NSLayoutConstraint!
    //for Layout 2
    @IBOutlet weak var blueLeadingConstraint: NSLayoutConstraint!
    @IBOutlet weak var blueTrailingYellowLeadingConstraint: NSLayoutConstraint!
    @IBOutlet weak var yellowTrailingConstraint: NSLayoutConstraint!
    var isLayout1:Bool = true
    override func viewDidLoad() {
    override func viewWillLayoutSubviews() {

    override func didReceiveMemoryWarning() {

    @IBAction func layoutSegmentValueChanged(sender: AnyObject) {
        let segment:UISegmentedControl = sender as! UISegmentedControl
        isLayout1 = segment.selectedSegmentIndex == 0
    override func updateViewConstraints() {
        if isLayout1 {
            //At first, deactivate layout2
            blueLeadingConstraint.active = false
            blueTrailingYellowLeadingConstraint.active = false
            yellowTrailingConstraint.active = false
            //Second, activate layout1
            yellowLeadingConstraint.active = true
            yellowTrailingBlueLeadingConstraint.active = true
            blueTrailingConstraint.active = true
             * You can also deactivate and activate constraints,
             * using NSLayoutConstraint's class methods.
//            NSLayoutConstraint.deactivateConstraints([
//                blueLeadingConstraint,
//                blueTrailingYellowLeadingConstraint,
//                yellowTrailingConstraint
//            ])
//            NSLayoutConstraint.activateConstraints([xxxx,  xxxx,  xxx])
            //At first, deactivate layout1
            yellowLeadingConstraint.active = false
            yellowTrailingBlueLeadingConstraint.active = false
            blueTrailingConstraint.active = false
            //Second, activate layout2
            blueLeadingConstraint.active = true
            blueTrailingYellowLeadingConstraint.active = true
            yellowTrailingConstraint.active = true

It is no problem wherever you change NSConstraint’s value in the code. But if complex changing NSConstraints anyware will be problem. It prefer to change in updateViewConstraints(). In the code activate or deactivate NSConstraint’s active property. Note: at first turn off NSConstraint and turn on new NSConstraint. That’s order is important. or you see error log in the console.

I tried to call updateViewConstraints() in viewWillAppear(), but it had a problem that not work in the app’s launch time. I struggled it. I found solution. I have to call in viewWillLayoutSubviews(), and work collectly.

>> project file (.zip)

Comments are closed.