0
votes

I need help in autolayouts. Am very new to Autolayouts and am not getting how to add auto layouts programmtically actually am getting below error.

When added to a view, the constraint's items must be descendants of that view (or the view itself). This will crash if the constraint needs to be resolved before the view hierarchy is assembled. Break on -[UIView(UIConstraintBasedLayout) _viewHierarchyUnpreparedForConstraint:] to debug. 2018-07-25 17:35:19.363248+0530

AutoLayoutsProgrammtically[4831:78876] *** Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to install constraint on view. Does the constraint reference something from outside the subtree of the view? That's illegal. constraint:UIButton:0x7f8e3ac0a6a0 (active, names: '|':UIView:0x7f8e3ad09cd0 )> view:>'

Below is the code :

 var button : UIButton = UIButton()
 override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(self.button)
// self.updateTheChanges()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewWillLayoutSubviews() {
updateTheChanges()
}
func updateTheChanges() {
button.translatesAutoresizingMaskIntoConstraints = false
button.titleLabel?.text = "dasdasdas"
button.backgroundColor = UIColor.black
button.titleLabel?.textColor = UIColor.white
//left edge
let leftEdgeConstraint = NSLayoutConstraint(item: button, attribute: NSLayoutAttribute.left, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.left, multiplier: 1.0, constant: 0)
//right edge
let rightEdgeConstraint = NSLayoutConstraint(item: button, attribute: NSLayoutAttribute.right, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.right, multiplier: 1.0, constant: 0)
// bottom edge
let topEdgeConstraint  = NSLayoutConstraint(item: button, attribute: NSLayoutAttribute.topMargin, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.topMargin, multiplier: 1.0, constant: 10)
// add all constraints
button.addConstraints([leftEdgeConstraint,rightEdgeConstraint,topEdgeConstraint])}
2
And here am not using any story board reference am only creating from class itself by programmtically.Deep kumar
Save yourself the pain and use SnapKit: github.com/SnapKit/SnapKitekscrypto
@ekscrypto i appreciate your help but i want in pure auto layout not any third partyDeep kumar
@mag_zbc Thanks for your time. I tried it in viewdidload even viewwillappear but none of them are working. Any other idea?Deep kumar
Also, don't make these calls in viewWillLayoutSubviews, because it can be called many times. You were better off doing it in viewDidLoad because it is called only once.matt

2 Answers

1
votes

First constraints should be added to self.view

import UIKit

class ViewController: UIViewController {

let button = UIButton(type: .system)

override func viewDidLoad() {
    super.viewDidLoad()

    button.setTitle("mytitle", for: .normal)

    button.setTitleColor(.green, for: .normal)

    button.backgroundColor = .black

    self.view.addSubview(button)

    button.translatesAutoresizingMaskIntoConstraints = false

    NSLayoutConstraint.activate([

        button.leftAnchor.constraint(equalTo: view.leftAnchor),

        button.rightAnchor.constraint(equalTo: view.rightAnchor),

        button.topAnchor.constraint(equalTo: view.topAnchor,constant:20)

   ])
  }

}

enter image description here

0
votes

You are adding constraints to the button but you should add them to self.view. You can check that Gist for full answer.

Change

button.addConstraints([...]) 

to

view.addConstraints([...])

Also for changing the titleLabel and titleColor you should use

button.setTitle("dasdasdas", for: .normal)
button.setTitleColor(.white, for: .normal)