'Unable to activate because they have no common ancestor IBOutlet and code
I am trying to add a constraint to a tableview I created and added to view programatically. I want to constraint it based on a UITextField
which is an IBOutlet
. However, I am getting the following error:
*** Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to activate constraint with anchors and because they have no common ancestor. Does the constraint or its anchors reference items in different view hierarchies? That's illegal.'
@IBOutlet weak var authorTextField: UITextField!
override func viewDidLoad() {
myTableView = MyTableView(frame: CGRect(x: 0, y: 80, width: 320, height: 120), style: .plain)
myTableView!.isHidden = false
myTableView!.backgroundColor = UIColor.green
self.view.addSubview(myTableView!)
myTableView.setConstraints(to: authorTextField) // <-- this fails
// MyTableView.swift ..
func setConstraints(to view: UIView)
self.translatesAutoresizingMaskIntoConstraints = false
self.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 8.0).isActive = true
self.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -8.0).isActive = true
}
How to add this constraint?
Solution 1:[1]
The answer is in the error message. Your property authorTextField is in another view hierarchy. Go into your storyboard and put the textfield in the same view. On another note, dont mix setting frames and autolayout constraints, i think your confusing yourself here. Instead of
MyTableView(frame: CGRect(x: 0, y: 80, width: 320, height: 120), style: .plain)
write
MyTableView(frame: CGRect.zero, style: .plain)
and add a height constraint to your setConstraints method
self.view.heightAnchor.constraint(equalToConstant: 120).isActive = true
Solution 2:[2]
if you didn't add your view to view hierarchy, you will have this problem. I added addSubview and work well
addSubview(view)
or
self.view.addSubview(view)
Solution 3:[3]
you should use it instead of your code : for set constraint you should modify your code to following:
func setConstraints(to view: UIView , superView: UIView) {
self.translatesAutoresizingMaskIntoConstraints = false
let leading = NSLayoutConstraint(item: self, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 0.8)
let trailing = NSLayoutConstraint(item: self, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1, constant: -0.8)
let width = NSLayoutConstraint(item: self, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 320)
let height = NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 120)
superView.addConstraints([leading, trailing])
self.addConstraints([width, height])
}
and the first part: it's better to define MyTableView objet to zero frame ( it just helps you to don't mistake) and send the view controller to constraint , because it needs to add constraints to hierarchy place. so do like following:
myTableView = MyTableView(frame: .zero, style: .plain)
myTableView!.isHidden = false
myTableView!.backgroundColor = UIColor.green
self.view.addSubview(myTableView!)
myTableView.setConstraints(to: authorTextField , superView: self)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | |
Solution 3 | mohsen |