I have a ViewController with a tableView. I've set it up in the Storyboard. Is there a way to set the constraints for the tableView programmatically? I've tried to set a IBOutlet from my tableView in the ViewController and added constraints to it. But that didn't work.
This is my ViewController
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
addTableViewConstraints()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func addTableViewConstraints() {
tableView.setTranslatesAutoresizingMaskIntoConstraints(false)
var topConstraint = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Top, multiplier: 1.0, constant: 20)
var leadingContraint = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Leading, multiplier: 1.0, constant: 0)
var trailingConstraint = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.Trailing, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Trailing, multiplier: 1.0, constant: 0)
var bottomConstraint = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Bottom, multiplier: 1.0, constant: 0)
self.view.addConstraints([topConstraint, leadingContraint, trailingConstraint, bottomConstraint])
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! UITableViewCell
cell.textLabel?.text = "Cell"
return cell
}
}
Or do I have to make my tableView through code as well?
Thank You!
You mentioned in one of your comments that you want to change the constraints when the user presses a button. You can achieve this in less code by making an outlet to the constraint. Find the constraint in the document outline page and CTRL + Drag to your class to create an outlet to the constraint. Then you can change the constant in code easier.
@IBOutlet weak var topConstraint: NSLayoutConstraint!
@IBOutlet weak var bottomConstraint: NSLayoutConstraint!
func buttonPressed() {
if (/* some condition */) {
self.topConstraint.constant += 8
self.bottomConstraint.constant += 8
} else {
// Return the constraints to normal, or whatever you want to do
}
}
Change you method addTableViewConstraints
in the following way:
func addTableViewConstraints() {
tableView.setTranslatesAutoresizingMaskIntoConstraints(false)
var topConstraint = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Top, multiplier: 1.0, constant: 20)
var leadingContraint = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Leading, multiplier: 1.0, constant: 0)
var trailingConstraint = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.Trailing, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Trailing, multiplier: 1.0, constant: 0)
var bottomConstraint = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Bottom, multiplier: 1.0, constant: 0)
NSLayoutConstraint.activateConstraints([topConstraint, leadingContraint, trailingConstraint, bottomConstraint])
}
UPDATE:
The NSIBPrototypingLayoutConstraint
constraints that you're running into (and that are causing exceptions) are auto-generated by Interface Builder in order to make your Storyboard or XIB view layout non-ambiguous. It's pretty sneaky about doing this, but it's automatically adding the minimum constraints required so that the position and size of each ambiguous view becomes fully specified.
The way to fix this issue is to add the minimum required constraints in Interface Builder so that each view's position & size is fully specified, then select each of these unwanted constraints, go to the right sidebar Attributes inspector, and check the box next to Placeholder - Remove at build time.
I resolved this in the following way:
- Open up the Storyboard view controller you're handling.
- Select your
UITableView
.
- Select the view controller and select Editor > Resolve Auto Layout Issues > Selected View in [ ] View Controller > Add Missing Constraints from the menu:
- Select all the constraints from your table view:
- Check from the right pane the following check box: Placeholder - Remove at build time:
Now you can add all the auto layout constraints manually in your code and without any warnings.
I hope this help you.
Let's say you have a button named myButton
and you would like to create its Bottom Space
constraint via code. The constant
of that constraint will be set to 500
.
Here's what a NSLayoutConstraint
looks like in Swift. Make sure to include this code in a function.
var constraintButton = NSLayoutConstraint (item: myButton,
attribute: NSLayoutAttribute.Bottom,
relatedBy: NSLayoutRelation.Equal,
toItem: self.view,
attribute: NSLayoutAttribute.Bottom,
multiplier: 1,
constant: 500)
// Add the constraint to the view
self.view.addConstraint(constraintButton)