Updating multiple view constraints at the same time

First, you seem to have over-constrained myView relative to its superview such that the constraints can't allow it to slide. You've pinned its leading and trailing edges plus, when adding the vertical constraint, you've pinned its center, too, by specifying NSLayoutFormatAlignAllCenterX.

That aside, perhaps the better way to think about it is that having two constraints that you have to update in sync suggests you're using the wrong constraints. You could have a constraint for the leading edge and then a constraint making myView's width equal to the width of self.view. That way, you only have to adjust the leading constraint's constant and both edges move as a consequence.

Also, you're using -setFrame:, which is a no-no with auto layout. You should be animating the constraints. You should set up constraints on newView such that its leading or trailing edge (as appropriate) equals the the neighboring edge of myView and its width equals that of self.view. Then, in the animation block, change the constant of the constraint determining the placement of myView (and, indirectly, newView) to slide them together. In the completion handler, install a constraint on newView to keep its leading edge coincident with self.view's, since it's the new myView.

BOOL left = (swipeDirection == UISwipeGestureRecognizerDirectionLeft);
float width = self.myView.frame.size.width;
float finalX = left ? -width : width;
NSString* layout = left ? @"[myView][newView(==mainView)]" : @"[newView(==mainView)][myView]";
NSDictionary* views = NSDictionaryOfVariableBindings(newView, myView, mainView);

[self.mainView addSubview:newView];
[self.mainView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:layout
                                                                      options:0
                                                                      metrics:nil
                                                                        views:views]];
[self.mainView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|newView|"
                                                                      options:0
                                                                      metrics:nil
                                                                        views:views]];
[self.mainView layoutIfNeeded];

// Slide old view out and new view in
[UIView animateWithDuration:0.4f
                      delay:0.0f
                    options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction
                 animations:^
        {
            self.myView.leadingConstraint.constant = finalX;
            [self.myView layoutIfNeeded];
        }
                 completion:^(BOOL finished)
        {
            [self.myView removeFromSuperview];
            self.myView = newView;
            NSLayoutConstraint* leading = [NSLayoutConstraint constraintWithItem:newView
                                                                       attribute:NSLayoutAttributeLeading
                                                                       relatedBy:NSLayoutRelationEqual
                                                                          toItem:self.view
                                                                       attribute:NSLayoutAttributeLeading
                                                                      multiplier:1.0f
                                                                        constant:0];
            self.myView.leadingConstraint = leading;
            [self.mainView addConstraint:leading];
        }];

Edited to answer the question more directly: No, there's no way in the public API to batch constraint updates so that the engine doesn't check them one-at-a-time as they're added or mutated by setting their constant.


To update multiple constraints at the same time, override updateConstraints with your update logic and call setNeedsUpdateConstraints to trigger updates. From Apple's Auto Layout Guide > Advanced Auto Layout > Changing Constraints:

To batch a change, instead of making the change directly, call the setNeedsUpdateConstraints method on the view holding the constraint. Then, override the view’s updateConstraints method to modify the affected constraints.

It's not as straightforward to update constraints this way so I recommend that you read the docs carefully before going down this route.