Michael
Michael

Reputation: 845

How do I overwrite a constraint

I have a UIButton that's constrained to the parent view like this:

[myButton constrainToParentView:NSLayoutAttributeCenterX];

and later in my code, I want to change the constraint to this:

[myButton constrainToParentView:NSLayoutAttributeLeading spaced:24];

But when the second line runs, it doesn't overwrite the first constraint. Instead both constraints exist. How do I overwrite the first constraint? I read that you have to set the constraint as a property, but I couldn't find any information on doing that for my case specifically.

Upvotes: 0

Views: 191

Answers (1)

DonMag
DonMag

Reputation: 77568

You probably don't want to use whatever method or extension you're currently using for constrainToParentView - or, you need to edit it to allow for saving references to the constraints.

Here's a simple example, using constraint methods directly. Very simple, and the comments should be clear. It creates a button, centers it horizontally, then swaps between leading and center constraints with each tap.

// SwapConstraintsViewController.h

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface SwapConstraintsViewController : UIViewController

@end

NS_ASSUME_NONNULL_END

and

// SwapConstraintsViewController.m

#import "SwapConstraintsViewController.h"

@interface SwapConstraintsViewController ()

@property (strong, nonatomic) UIButton *myButton;

@property (strong, nonatomic) NSLayoutConstraint *centerXLayoutConstraint;
@property (strong, nonatomic) NSLayoutConstraint *leadingLayoutConstraint;

@end

@implementation SwapConstraintsViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    _myButton = [UIButton new];
    _myButton.translatesAutoresizingMaskIntoConstraints = NO;
    _myButton.backgroundColor = [UIColor redColor];
    [_myButton setTitle:@"Test Button" forState:UIControlStateNormal];

    [self.view addSubview:_myButton];

    // constrain the button 100-pts from the top of the view
    [_myButton.topAnchor constraintEqualToAnchor:self.view.topAnchor constant:100.0].active = YES;

    // create centerX constraint
    _centerXLayoutConstraint = [_myButton.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor constant:0.0];

    // create leading constraint
    _leadingLayoutConstraint = [_myButton.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:24.0];

    // activate centerX constraint
    _centerXLayoutConstraint.active = YES;

    [_myButton addTarget:self action:@selector(didTap:) forControlEvents:UIControlEventTouchUpInside];

}

- (void)didTap:(id)sender {

    if ([_centerXLayoutConstraint isActive]) {
        // de-activate center first, then activate leading
        _centerXLayoutConstraint.active = NO;
        _leadingLayoutConstraint.active = YES;
    } else {
        // de-activate leading first, then activate center
        _leadingLayoutConstraint.active = NO;
        _centerXLayoutConstraint.active = YES;
    }

}

@end

Upvotes: 1

Related Questions