KaasCoder
KaasCoder

Reputation: 251

NSLayoutConstraints with NSLayoutAttributeTrailing not as expected

I have an array with two new constraints.

When I set these constraints the button is placed 20 and 90 pix from the center of the superview. I want the button 20px from the bottom and 90px from the right of the superview. What am I doing wrong? I create an array with two constraints:

NSLayoutConstraint *bottomTrailingConstraint = [NSLayoutConstraint constraintWithItem:_gameSettingsButton
                                                                            attribute:NSLayoutAttributeTrailing
                                                                            relatedBy:NSLayoutRelationEqual
                                                                               toItem:_gameSettingsButton.superview
                                                                            attribute:NSLayoutAttributeTrailing
                                                                           multiplier:1.0f
                                                                             constant:90.0f];

NSLayoutConstraint *bottomSpaceConstraint = [NSLayoutConstraint constraintWithItem:_gameSettingsButton
                                                                         attribute:NSLayoutAttributeBottom
                                                                         relatedBy:NSLayoutRelationEqual
                                                                            toItem:_gameSettingsButton.superview
                                                                         attribute:NSLayoutAttributeBottom
                                                                        multiplier:1.0f
                                                                          constant:20.0f];

_bottomConstraintsArray = @[bottomTrailingConstraint, bottomSpaceConstraint];

I remove the old constraints and then add the new constraints:

NSArray *oldconstraints = _gameSettingsButton.constraints;
[_gameSettingsButton.superview removeConstraints: oldconstraints];
[_gameSettingsButton.superview addConstraints:_bottomConstraintsArray];

I also tried: [_gameSettingsButton.superview updateConstraints] but that changes nothing.

Any help would be greatly appreciated.

Upvotes: 1

Views: 2191

Answers (1)

Ken Thomases
Ken Thomases

Reputation: 90521

This:

NSLayoutConstraint *bottomTrailingConstraint = [NSLayoutConstraint constraintWithItem:_gameSettingsButton
                                                                            attribute:NSLayoutAttributeTrailing
                                                                            relatedBy:NSLayoutRelationEqual
                                                                               toItem:_gameSettingsButton.superview
                                                                            attribute:NSLayoutAttributeTrailing
                                                                           multiplier:1.0f
                                                                             constant:90.0f];

means:

_gameSettingsButton.trailing == _gameSettingsButton.superview.trailing * 1 + 90

That will make the button's trailing edge outside of the superview. Assuming left-to-right layout (so "trailing" means "right"), the button's right edge will be 90 points to the right of the superview.

Similarly, this:

NSLayoutConstraint *bottomSpaceConstraint = [NSLayoutConstraint constraintWithItem:_gameSettingsButton
                                                                         attribute:NSLayoutAttributeBottom
                                                                         relatedBy:NSLayoutRelationEqual
                                                                            toItem:_gameSettingsButton.superview
                                                                         attribute:NSLayoutAttributeBottom
                                                                        multiplier:1.0f
                                                                          constant:20.0f];

means:

_gameSettingsButton.bottom == _gameSettingsButton.superview.bottom * 1 + 20

Again, this will put the button outside of the superview. The button's bottom edge will be down 20 points from the bottom of the superview.

You either want to swap the first and second items or you want to negate the constant.

Also, you are querying the constraints from the button and then removing those constraints from the superview. Well, since the constraints you queried are not on the superview, that does nothing. (In fact, the result of your query is probably an empty array since nothing ever adds any constraints to the button itself.) You probably meant to query the constraints on the superview but I suspect there will be constraints unrelated to the button which you don't want to remove. So, you will need to remember the constraints you set up for the button (probably in an instance variable) and remove those. If the initial constraints were set up in IB, then you'll need to set up an outlet to track them.

Upvotes: 4

Related Questions