Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIStoryboard how to replace constraints programmatically?

I have a view controller laid out in a storyboard with autolayout enabled and am looking for a way to change constraints to allow for my view to rotate into landscape and rearrange buttons on the screen. When I try the code below, I get about two dozen "unable to satisfy constraints, breaking constraint..." messages that I cannot really decode.

Is there a way to dynamically replace constraints from a storyboard with constraints that I specify programmatically? I want to completely override the layout of the buttons that I defined in a storyboard.

-(void)updateViewConstraints
{
    [super updateViewConstraints];

    self.loginButton.translatesAutoresizingMaskIntoConstraints = NO;
    self.getStartedButton.translatesAutoresizingMaskIntoConstraints = NO;
    self.takeTourButton.translatesAutoresizingMaskIntoConstraints = NO;



    [self.loginButton removeConstraints:self.loginButton.constraints];
    [self.getStartedButton removeConstraints:self.getStartedButton.constraints];
    [self.takeTourButton removeConstraints:self.takeTourButton.constraints];


    one = self.loginButton;
    two = self.getStartedButton;
    three = self.takeTourButton;


    NSDictionary *metrics = @{@"height":@50.0,@"width":@100.0,@"leftSpacing":@110.0};
    NSDictionary *views = NSDictionaryOfVariableBindings(one,two,three);

    [self.view removeConstraints:activeTestLabelConstraints];
    [activeTestLabelConstraints removeAllObjects];

    if(isRotatingToLandscape)
    {

        [self registerConstraintsWithVisualFormat:@"|-[one(two)]-[two(three)]-[three]-|" options:NSLayoutFormatAlignAllTop | NSLayoutFormatAlignAllBottom metrics:metrics views:views];
        [self registerConstraintsWithVisualFormat:@"V:[one(height)]-|" options:0 metrics:metrics views:views];

    }else
    {

        [self registerConstraintsWithVisualFormat:@"|-leftSpacing-[one(width)]" options:0 metrics:metrics views:views];
        [self registerConstraintsWithVisualFormat:@"[two(width)]" options:0 metrics:metrics views:views];
        [self registerConstraintsWithVisualFormat:@"[three(width)]" options:0 metrics:metrics views:views];
        [self registerConstraintsWithVisualFormat:@"V:[one(height)]-[two(75)]-[three(100)]-|" options:NSLayoutFormatAlignAllCenterX metrics:metrics views:views];
    }


}

Updated with Rob's answer, here's the method to remove constraints that I use

-(void)removeConstraintForView:(UIView*)viewToModify
{

    UIView* temp = viewToModify;
    [temp removeFromSuperview];
    [self.view addSubview:temp];

}
like image 783
Alex Stone Avatar asked Jul 25 '13 19:07

Alex Stone


1 Answers

It sounds like you want to just remove all the constraints on a view. Since constraints on a view are often held by an ancestor of the view, it's not obvious how to remove all of the constraints easily. But it is actually pretty easy.

Removing a view from the view hierarchy removes any constraints betwixt the view and other views outside of it. So just remove your view from its superview and then add it back:

// Remove constraints betwixt someView and non-descendants of someView.
UIView *superview = someView.superview;
[someView removeFromSuperview];
[superview addSubview:someView];

If there are any constraints betwixt someView and its descendants, those constraints might be held by someView itself (but cannot be held by any descendants of someView). If you want to remove those constraints also, you can do so directly:

// Remove any remaining constraints betwixt someView and its descendants.
[someView removeConstraints:[someView constraints]];
like image 83
rob mayoff Avatar answered Dec 08 '22 00:12

rob mayoff