I want to do this programmatically without Interface Builder. I want to add a UITextField to my iOS app a constant distance from the bottom of the app view. I've looked at a lot of existing questions and answers. None are in Swift and this topic seems relatively undocumented.
There are several somewhat related answers out there, but here are all the pieces it took to get this working:
1) I needed to create a constraint like
let bottomConstraint : NSLayoutConstraint = NSLayoutConstraint.constraintsWithVisualFormat("V:[inputBox]-50-|", options: NSLayoutFormatOptions(0), metrics: nil, views: ["inputBox": inputBox])[0] as! NSLayoutConstraint
This uses Swift's domain specific language "visual format language" (VFL): V:[inputBox]-50-|
, where the 'V' means vertical, 50 is a number of pixels and the '|' refers to the bottom of the parent view.
2) The UITextField had to be added to the view before adding the constraint to the view so '|' above could find the parent view.
3) Once I used one NSLayoutConstraint I had to use them for all aspects of sizing and positioning for this element. Hence I had to add these two lines to describe its width and height:
let heightConstraint : NSLayoutConstraint = NSLayoutConstraint.constraintsWithVisualFormat("V:[inputBox(==70)]", options: NSLayoutFormatOptions(0), metrics: nil, views: ["inputBox": inputBox])[0] as! NSLayoutConstraint
let widthConstraint : NSLayoutConstraint = NSLayoutConstraint.constraintsWithVisualFormat("H:[inputBox(==superview)]", options: NSLayoutFormatOptions(0), metrics: nil, views: ["inputBox": inputBox, "superview":self.view])[0] as! NSLayoutConstraint
4) To get my UITextField to interact correctly with VFL I had to add this line:
inputBox.setTranslatesAutoresizingMaskIntoConstraints(false)
Putting it all together:
let inputBox = UITextField(frame: rect)
inputBox.backgroundColor = UIColor.yellowColor()
inputBox.setTranslatesAutoresizingMaskIntoConstraints(false)
self.view.addSubview(inputBox)
let bottomConstraint : NSLayoutConstraint = NSLayoutConstraint.constraintsWithVisualFormat("V:[inputBox]-50-|", options: NSLayoutFormatOptions(0), metrics: nil, views: ["inputBox": inputBox])[0] as! NSLayoutConstraint
let heightConstraint : NSLayoutConstraint = NSLayoutConstraint.constraintsWithVisualFormat("V:[inputBox(==70)]", options: NSLayoutFormatOptions(0), metrics: nil, views: ["inputBox": inputBox])[0] as! NSLayoutConstraint
let widthConstraint : NSLayoutConstraint = NSLayoutConstraint.constraintsWithVisualFormat("H:[inputBox(==superview)]", options: NSLayoutFormatOptions(0), metrics: nil, views: ["inputBox": inputBox, "superview":self.view])[0] as! NSLayoutConstraint
view.addConstraint(bottomConstraint)
view.addConstraint(heightConstraint)
view.addConstraint(widthConstraint)