Gold Challenge - Using Constraints


#1

I figured I’d do well to have a poke around the new way of doing things, with constraints, so here’s my attempt at the Gold challenge using Auto Layout. All comments welcome, as I’m stumbling in the dark a bit here :slight_smile:

  1. Create a button on the left-hand side using the Xib layout editor; make sure it’s set up nicely with auto layout constraints.
  2. Create an IBOutlet instance variable of type NSLayoutConstraint* for the constraint between the left of the button and the parent view, in HeavyViewController, and drag a connection from that left-hand-side constraint to the outlet to link it up.

(That lets you programatically play with the left-hand constraint easily.)

  1. Create an NSArray* instance variable in HeavyViewController called landScapeConstraints.

(This will be used for keeping hold of extra constraints I add during rotation to landscape.)

  1. Code willAnimateRotationToInterfaceOrientation: toInterfaceOrientation:
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    UIView* v = [self view];
    
    if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
        // Move the button to the right.
        if (!landscapeConstraints) {
            landscapeConstraints =[NSLayoutConstraint
                                   constraintsWithVisualFormat:@"[button]-|"
                                   options:NSLayoutFormatDirectionLeadingToTrailing
                                   metrics:nil
                                   views:[NSDictionary dictionaryWithObject:button forKey:@"button"]];
        }
        
        [v addConstraints:landscapeConstraints];
        [v removeConstraint:leftConstraint];
    } else if (UIInterfaceOrientationIsPortrait(toInterfaceOrientation)) {
        // Though I think I could assume that it's portrait
        [v removeConstraints:landscapeConstraints];
        [v addConstraint:leftConstraint];
    }
}

So, basically, when rotating to landscape, I remove the left-hand constraint from the view, and add a right-hand constraint (using constraintsWithVisualFormat, mostly because it’s cool, rather than because I really need to.) I keep an array of these constraints so I can use them both when the phone’s moved back to portrait (removing them using removeConstraints) and the next time we rotate to landscape, by adding them again without having to bother with constraintsWithVisualFormat, which I’m guessing is more expensive.

I’m guessing I don’t need to deallocate anything, or worry about the view being destroyed while I’ve got ahold of constraints that point at it, because both the view controller and the view will stay around for the life of the application?

It seems to work, anyway: the button is nicely auto-layed-out below the picture and above the lower buttons, and when rotated, it animates cutely over to the right-hand side, in the similar relative position.