TheNotSoWise
TheNotSoWise

Reputation: 899

Programmatically disable auto-layout constraint

Is there any programatic way to temporarily disable an auto-layout constraint? I do not want that constraint to be considered for a certain period of time at all until I need it again.

Upvotes: 29

Views: 32675

Answers (3)

oyalhi
oyalhi

Reputation: 3994

When developing for iOS 8.0 or later, just use isActive property of NSLayoutConstraint after creating your IBOutlet.

UPDATED

  • to have strong reference to the outlet per below suggestion, thank you @rob mayoff.
  • to use .isActive instead of .active with Swift 4 per below suggestion, thank you @Mohit Singh.

your cell would have the following outlet:

@IBOutlet var photoBottomConstraint: NSLayoutConstraint!

and you would access the constraint in willDisplayCell like:

myCell.photoBottomConstraint.isActive = false

and when you need it again:

myCell.photoBottomConstraint.isActive = true

Upvotes: 47

Yuchen
Yuchen

Reputation: 33036

Base on oyalhi's answer, also want to point out that you have to make a strong reference to your constraints if you want to make it inactive:

@IBOutlet var photoBottomConstraint: NSLayoutConstraint!

It is not abvious, but if you are using weak reference, photoBottomConstraint could be nil after this call:

myCell.photoBottomConstraint.active = false

Upvotes: 10

iluvcapra
iluvcapra

Reputation: 9464

You use NSView's removeConstraint:; if you've created the constraint in the interface builder you connect it to the code through an IBOutlet

class MyView : NSView {
    @IBOutlet var temporaryConstraint : NSLayoutConstraint! 

    var constraint : NSLayoutConstraint! = nil /* my strong link */ 
    var constraintShowing : Bool

    func awakeFromNib() {
         constraint = temporaryConstraint
    }

    func toggleLayoutConstraint(sender : AnyObject) -> () {
         if constraintShowing {
             self.removeConstraint( constraint )      
         } else {
             self.addConstraint( constraint )   
         }
         constraintShowing = !constraintShowing
    }
}

Sort of like the dance we used to have to do with NSTableColumns in the 10.4 days before they could be hidden.


You can also do a little controller gadget

class ConstraintController {
    var constraint : NSLayoutConstraint
    var view       : NSView
    var show       : Bool {
        didSet {
            if show {
                view.addConstraint(constraint)
            } else {
                view.removeConstraint(constraint)
            }
        }
    } 

    init (c : NSLayoutConstraint, inView : NSView) {
        constraint = c
        view = inView
        show = true
    }
}

class MyView : NSView {
    @IBOutlet var temporaryConstraint : NSLayoutConstraint!
    var control : ConstraintController? = nil

    func awakeFromNib() -> () { 
        control = ConstraintController(temporaryConstraint, inView: self)
    }

    func show(sender : AnyObject!) -> () {
        control!.show
    }

    func hide(sender : AnyObject!) -> () {
        control!.hide
    }
}

More lines but arguably easier to understand and less hackish.

Upvotes: 3

Related Questions