I have a collection view which has a textView for each cell. This is my textview constraint set up
textView.topAnchor.constraint(equalTo: object1.bottomAnchor).isActive = true
textView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
...and width and height of my textView.
Now, I want to change topAnchor of my textView to object 2 bottom anchor instead of object 1 bottom anchor due to a if condition. However, when I enter the code below, I get Will attempt to recover by breaking constraint error.
Does anyone know a way to change top anchor once it is already set up?
if (aCondition){
textView.topAnchor.constraint(equalTo: object2.bottomAnchor).isActive = true
}else{
textView.topAnchor.constraint(equalTo: object1.botttomAnchor).isActive = true
}
Some editing is also possible directly from the Size inspector. Clicking the Edit button in any of the constraints brings up a popover where you can change the constraint's relationship, constant, priority, or multiplier.
Since multiplier is a read-only property and you can't change it, you need to replace the constraint with its modified clone.
You have to deactivate the old active constraint. Right now you are just adding new constraints to the view. So first I would suggest you create two properties that would keep references to constraints:
fileprivate var topConstraint1: NSLayoutConstraint?
fileprivate var topConstraint2: NSLayoutConstraint?
Then at the beginning, when you are creating UI, initialize them properly:
topConstraint1 = textView.topAnchor.constraint(equalTo: object1.bottomAnchor)
topConstraint2 = textView.topAnchor.constraint(equalTo: object2.bottomAnchor)
And activate the one that you want to be active as first:
topConstraint1?.isActive = true
Then when you want to change the constraints, you first deactivate the one that should be deactivated, and then activate the correct one:
if aCondition {
topConstraint1?.isActive = false
topConstraint2?.isActive = true
} else {
topConstraint2?.isActive = false
topConstraint1?.isActive = true
}
P.S.: You always want to first deactivate the old one and then activate the new one, otherwise for that moment when you activate the new one it would conflict with the old one and cause warnings in console.
P.S.2: If you want to activate several constraints at once, use NSLayoutConstraint.activate(_:)
- as per documentation, it is more efficient:
Typically, using this method is more efficient than activating each constraint individually.
So e.g., instead of:
someConstraint1.isActive = true
someConstraint2.isActive = true
use rather:
NSLayoutConstraint.activate([someConstraint1, someConstraint2])
The same applies to deactivating constraints and NSLayoutConstraint.deactivate(_:)
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With