Swift NSLayoutConstraint programatically sample code
Created By: Debasis Das (16-Jan-2016)
In this post we will apply constraints to 4 views in a NSWindow using swift NSLayoutConstraint programatically . This approach is much more tedious and lengthy in comparison to the constraintsWithVisualFormat Approach.
Its upto the developers discretion to either use the visual format or constrain initializer approach.
Note: The autoLayOut checkbox is switched off in the XIB and all the constraints will be added programmatically
In the below sample the following behaviour is desired
- Red View – Header and is of constant height- width is resizable as the window resizes
- Green View – Search Section is of constant height – width of the green view increases as the window resizes
- Blue View – Data View is of dynamic width and height and increases as the screen resizes.
- Cyan View – Footer section is of fixed height and dynamic width
- The screen has a minimum width and height that is derived from the sections
Sample Code
NSLayoutConstraint(
item: AnyObject,
attribute: NSLayoutAttribute,
relatedBy: NSLayoutRelation,
toItem: AnyObject?>,
attribute: NSLayoutAttribute,
multiplier: CGFloat,
constant: CGFloat)
// AppDelegate.swift // NSLayoutConstraintSwiftSampleCode // Created by Debasis Das on 15/01/16. // Copyright © 2016 Knowstack. All rights reserved. import Cocoa @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { @IBOutlet weak var window: NSWindow! @IBOutlet weak var headerView: HeaderView! @IBOutlet weak var searchView: SearchView! @IBOutlet weak var dataView: DataView! @IBOutlet weak var footerView: FooterView! func applicationDidFinishLaunching(aNotification: NSNotification) { // Insert code here to initialize your application } func applicationWillTerminate(aNotification: NSNotification) { // Insert code here to tear down your application } override func awakeFromNib() { autolayoutUsingConstraint() } func autolayoutUsingConstraint(){ self.headerView.translatesAutoresizingMaskIntoConstraints = false self.searchView.translatesAutoresizingMaskIntoConstraints = false self.dataView.translatesAutoresizingMaskIntoConstraints = false self.footerView.translatesAutoresizingMaskIntoConstraints = false let mainView = self.window.contentView //HeaderView //Header = 20 from left edge of screen let cn1 = NSLayoutConstraint(item: headerView, attribute: .Leading, relatedBy: .Equal, toItem: mainView, attribute: .Leading, multiplier: 1.0, constant: 20) //Header view trailing end is 20 px from right edge of the screen let cn2 = NSLayoutConstraint(item: headerView, attribute: .Trailing, relatedBy: .Equal, toItem: mainView, attribute: .Trailing, multiplier: 1.0, constant: -20) //Header view height = constant 60 let cn3 = NSLayoutConstraint(item: headerView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 60) //Header view width greater than or equal to 400 let cn4 = NSLayoutConstraint(item: headerView, attribute: .Width, relatedBy: .GreaterThanOrEqual, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 400) //Header view vertical padding from the top edge of the screen = 20 let cn5 = NSLayoutConstraint(item: headerView, attribute: .Top, relatedBy: .Equal, toItem: mainView, attribute: .Top, multiplier: 1.0, constant: 20) //Search Section //search section 20px from left edge of screen let cn6 = NSLayoutConstraint(item: searchView, attribute: .Leading, relatedBy: .Equal, toItem: mainView, attribute: .Leading, multiplier: 1.0, constant: 20) //search section 20px from the right edge of the screen let cn7 = NSLayoutConstraint(item: searchView, attribute: .Trailing, relatedBy: .Equal, toItem: mainView, attribute: .Trailing, multiplier: 1.0, constant: -20) //search section height = constant 100 let cn8 = NSLayoutConstraint(item: searchView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 100) //search section width >=400 let cn9 = NSLayoutConstraint(item: searchView, attribute: .Width, relatedBy: .GreaterThanOrEqual, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 400) let cn10 = NSLayoutConstraint(item: searchView, attribute: .Top, relatedBy: .Equal, toItem: headerView, attribute: .Bottom, multiplier: 1.0, constant: 20) //Data Section let cn11 = NSLayoutConstraint(item: dataView, attribute: .Leading, relatedBy: .Equal, toItem: mainView, attribute: .Leading, multiplier: 1.0, constant: 20) let cn12 = NSLayoutConstraint(item: dataView, attribute: .Trailing, relatedBy: .Equal, toItem: mainView, attribute: .Trailing, multiplier: 1.0, constant: -20) //Data section height is >=300 and width is >=400 let cn13 = NSLayoutConstraint(item: dataView, attribute: .Height, relatedBy: .GreaterThanOrEqual, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 300) let cn14 = NSLayoutConstraint(item: dataView, attribute: .Width, relatedBy: .GreaterThanOrEqual, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 400) let cn15 = NSLayoutConstraint(item: dataView, attribute: .Top, relatedBy: .Equal, toItem: searchView, attribute: .Bottom, multiplier: 1.0, constant: 20) //Footer Section let cn16 = NSLayoutConstraint(item: footerView, attribute: .Leading, relatedBy: .Equal, toItem: mainView, attribute: .Leading, multiplier: 1.0, constant: 20) let cn17 = NSLayoutConstraint(item: footerView, attribute: .Trailing, relatedBy: .Equal, toItem: mainView, attribute: .Trailing, multiplier: 1.0, constant: -20) let cn18 = NSLayoutConstraint(item: footerView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 50) let cn19 = NSLayoutConstraint(item: footerView, attribute: .Width, relatedBy: .GreaterThanOrEqual, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 400) let cn20 = NSLayoutConstraint(item: footerView, attribute: .Top, relatedBy: .Equal, toItem: dataView, attribute: .Bottom, multiplier: 1.0, constant: 20) let cn21 = NSLayoutConstraint(item: footerView, attribute: .Bottom, relatedBy: .Equal, toItem: mainView, attribute: .Bottom, multiplier: 1.0, constant: -20) mainView?.addConstraint(cn1) mainView?.addConstraint(cn2) mainView?.addConstraint(cn3) mainView?.addConstraint(cn4) mainView?.addConstraint(cn5) mainView?.addConstraint(cn6) mainView?.addConstraint(cn7) mainView?.addConstraint(cn8) mainView?.addConstraint(cn9) mainView?.addConstraint(cn10) mainView?.addConstraint(cn11) mainView?.addConstraint(cn12) mainView?.addConstraint(cn13) mainView?.addConstraint(cn14) mainView?.addConstraint(cn15) mainView?.addConstraint(cn16) mainView?.addConstraint(cn17) mainView?.addConstraint(cn18) mainView?.addConstraint(cn19) mainView?.addConstraint(cn20) mainView?.addConstraint(cn21) } } class HeaderView: NSView { override func drawRect(dirtyRect: NSRect) { super.drawRect(dirtyRect) NSColor.redColor().setFill() NSRectFill(dirtyRect); } } class SearchView: NSView { override func drawRect(dirtyRect: NSRect) { super.drawRect(dirtyRect) NSColor.greenColor().setFill() NSRectFill(dirtyRect); } } class DataView: NSView { override func drawRect(dirtyRect: NSRect) { super.drawRect(dirtyRect) NSColor.blueColor().setFill() NSRectFill(dirtyRect); } } class FooterView: NSView { override func drawRect(dirtyRect: NSRect) { super.drawRect(dirtyRect) NSColor.cyanColor().setFill() NSRectFill(dirtyRect); } }
The above sample code can be downloaded hereNSLayoutConstraint Swift Sample Code
Also Read constraintsWithVisualFormat
Simple Example on constraintsWithVisualFormat
Detailed Example on constraintsWithVisualFormat
“self.window.contentView” is not an option for me in swift 4? I cannot find a solution. Please help
Fixed the problem. Just used the view in the view controller instead of contentView. Great tutorial above, thanks.