CizooDev CizooDev - 23 days ago 5
iOS Question

How to modify programmatically constraints of UIButton

I have 2 buttons with different constraints write in the storyboard.
In my code, I have to tell my first button to take the same constraint of the second button (height, width, and position) but I do not know how to do this without necessarily passing by "subview". I have 2 outlets for my buttons.

@IBOutlet weak var likesButton: UIButton!
@IBOutlet weak var shareButton: UIButton!


My interface is build like that :

-

VIEW
a)...View
b)...View
c) ContentView
1)likeButton
2)shareButton
3)...
d)...


I tried like this :

self.contentView.translatesAutoresizingMaskIntoConstraints = false
self.shareButton.removeConstraints(self.shareButton.constraints) // Old Constraints
self.shareButton.addConstraints(self.likeButton.constraints) // New Constraints
self.shareButton.updateConstraintsIfNeeded()
self.shareButton.layoutIfNeeded()


And after I have this error :

*** 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:<NSLayoutConstraint:0x14cfe7600 H:[UIButton:0x14cfb7bd0(40)]> view:<UIButton: 0x14e30fa60; frame = (494 528; 26 31); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x14e30f410>>'





Thx in advance.

Answer

Does the constraint reference something from outside the subtree of the view?

This is as if it said...

Does the constraints of likeButton reference something from outside the subtree of the shareButton?

So, the likeButton constraint references (like the likeButton itself) are completely outside the shareButtons view hierarchy. They can't be added this way.

You could instead do:

self.view.removeConstraints(self.shareButton.constraints)
self.view.addConstraints(self.likeButton.constraints)

But this won't accomplish whatever you're trying to do.

A constraint is more than just a number and dimension. It also defines which two objects are constrained. So trying to map one views constraints to another like that won't work because it doesn't change which views are referenced in the constraint.

You can probably hack out a way to do it using outlets to the various constraints and pulling the constraint constants out of one view and assigning them to the other.