Reputation: 5303
I want to add identifiers to all my constraints so I can debug an issue. The problem is that I don’t create all my constraints directly if I use anchors. I can create a constraint:
let constraint = NSLayoutConstraint(item: view, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 60.0)
but then I’d have to add it to the view, not the heightAnchor (there is no .addConstraint() method associated with UIStackViews)
So how do I add identifiers to the constraints auto-generated by these lines of code:
view.heightAnchor.constraint(equalToConstant: 60.0).isActive = true
view.widthAnchor.constraint(equalToConstant: 60.0).isActive = true
anchors are supposed to make programming auto layout easier, but surely not at the expense of being unable to debug properly? If I can’t add identifiers, how do I debug my “unsatisfiable” constraints exception?
Upvotes: 0
Views: 1479
Reputation: 4760
I have a different approach using Swift 4.2. I hope that may be useful.
extension UIView{
func getConstraint(forAttribute attribute:NSLayoutConstraint.Attribute)->NSLayoutConstraint?{
for aConstraint in constraints{
if aConstraint.firstAttribute == attribute{
return aConstraint
}
}
return nil
}
}
so you can do;
@IBOutlet weak var confirmButton: MainButton!{
didSet{
confirmButton.getConstraint(forAttribute: .height)!.identifier = aID
confirmButton.isEnabled = false
}
}
or
myOtherButton.getConstraint(forAttribute: .height)?.identifier = "newIdentifier"
Upvotes: 1
Reputation: 1864
Look at the answer I gave in this question. It will give you an answer to your question.
(there is no .addConstraint() method
Yes, there is:
NSLayoutConstraint.activate([constraintvariable])
Edit:
Alright, if I understand your question correctly:
let vHeightConstraint = self.view.heightAnchor.constraint(equalToConstant: 60.0);
vHeightConstraint.isActive = true
vHeightConstraint.identifier = "Your identifier"
This way you'll have a variable for you constraint and that will be available under debugging to see it's value.
Upvotes: 2
Reputation:
I use arrays and activate/deactivate them:
var p = [NSLayoutConstraint]() // portrait constraints
var l = [NSLayoutConstraint]() // landscape constraints
// (an example of this) pin segmentedView to top
p.append(segmentedControl.topAnchor.constraint(equalTo: imageLayout.topAnchor))
p.append(segmentedControl.widthAnchor.constraint(equalToConstant: 300))
p.append(segmentedControl.centerXAnchor.constraint(equalTo: imageLayout.centerXAnchor))
l.append(segmentedControl.topAnchor.constraint(equalTo: imageLayout.topAnchor))
l.append(segmentedControl.widthAnchor.constraint(equalToConstant: 300))
l.append(segmentedControl.centerXAnchor.constraint(equalTo: imageLayout.centerXAnchor))
public func setOrientation(_ p:[NSLayoutConstraint], _ l:[NSLayoutConstraint]) {
NSLayoutConstraint.deactivate(l)
NSLayoutConstraint.deactivate(p)
if self.bounds.width > self.bounds.height {
NSLayoutConstraint.activate(l)
} else {
NSLayoutConstraint.activate(p)
}
}
You get the idea.... move your constraints into an array and activate/deactivate as needed.
Upvotes: 1
Reputation: 450
Your code returns you constraint, so you can add identifier to it like this
let myConstraint = view.heightAnchor.constraint(equalToConstant: 60.0)
myConstraint.identifier = "myIdentifier"
myConstraint.isActive = true
Upvotes: 2