Reputation: 2154
I try to use auto layout programmatically by visual format language on a view which is on storyboard but failed. The code is as below: (Btw, the storyboard which shows bView is not important, so I didn't upload storyboard's picture. And I didn't setup any constrain on storyboard.)
class ViewController: UIViewController {
@IBOutlet var bView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
bView.translatesAutoresizingMaskIntoConstraints = false
var allConstraints = [NSLayoutConstraint]()
let vC = NSLayoutConstraint.constraintsWithVisualFormat("V:|-[bView]-|", options: [], metrics: nil, views: ["bView":bView])
let hC = NSLayoutConstraint.constraintsWithVisualFormat("H:|-[bView]-|", options: [], metrics: nil, views: ["bView":bView])
allConstraints += vC
allConstraints += hC
NSLayoutConstraint.activateConstraints(allConstraints)
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
}
}
But when it executes, it shows error:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse constraint format: Unable to interpret '|' character, because the related view doesn't have a superview V:|-[bView]-| ^'
I guess maybe the superView (the view of the viewController) did add on the mainWindow. So I tried to fix this problem by moving the code to viewWillLayoutSubviews(). As Below:
class ViewController: UIViewController {
@IBOutlet var bView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
bView.translatesAutoresizingMaskIntoConstraints = false
var allConstraints = [NSLayoutConstraint]()
let vC = NSLayoutConstraint.constraintsWithVisualFormat("V:|-[bView]-|", options: [], metrics: nil, views: ["bView":bView])
let hC = NSLayoutConstraint.constraintsWithVisualFormat("H:|-[bView]-|", options: [], metrics: nil, views: ["bView":bView])
allConstraints += vC
allConstraints += hC
NSLayoutConstraint.activateConstraints(allConstraints)
}
}
Then it shows a really funny wrong result.
So, how do I layout a view which is on storyboard programmatically?
What's more, there's a funny result like this: (It's not related to the question directly, but you can try it for fun!)
With code:
class ViewController: UIViewController {
@IBOutlet var bView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
bView.translatesAutoresizingMaskIntoConstraints = false
}
}
Upvotes: 1
Views: 524
Reputation: 154641
If you are trying to constrain the blue rectangle, then your first problem is that your bView
outlet is incorrectly wired to your top level view (the white background). Delete that connection in the Connections Inspector and then wire the blue view to bView
.
If you add a view in Interface Builder, but don't give it any constraints, then Xcode will add 4 constraints at build time. If you click on your view, you will see the following message in the Size Inspector:
The selected views have no constraints. At build time, explicit left, top, width, and height constraints will be generated for the view.
So, your view is already fully specified. If you add any more constraints in code you will have conflicts.
So, how can you add constraints in code for a view laid out in the Storyboard? You need to do the following:
Add explicit constraints in the Storyboard for left, top, width, and height.
Edit these 4 constraints in the Size Inspector and check the box next to Placeholder [] Remove at build time.
Then, these 4 constraints will be removed at build time leaving the view without constraints. Now your code is free to add constraints.
Upvotes: 1