1

Simplifying my example, let's say I have three squares on a basic view controller. In portrait mode, these squares are stacked on top of each other, and have 20 pixels or so of vertical spacing. So something like this:

X
X
X

In landscape mode, the 3rd X will get cut off, so I'd like to make it so they look like this:

XXX

in other words, have the bottom ones come up and be next to the top one (with 20 pixels or so of horizontal spacing between each).

what's the approach to do something like this with autolayouts, constraints, and size classes? Do I programmatically delete and re-add constraints? Just curious from an overall perspective how to achieve something like this.

Thanks!

rmaddy
  • 314,917
  • 42
  • 532
  • 579
NullHypothesis
  • 4,286
  • 6
  • 37
  • 79
  • Look at my answer here, http://stackoverflow.com/questions/24499035/possible-to-transform-view-on-previous-view-controller-when-screen-orientation-c/24513954#24513954 – rdelmar Jul 14 '14 at 03:42

1 Answers1

0

You can use the priority of NSLayoutConstraint

Auto Layout set views with higher priority of constraints.

for Portrait

Set the priority of leading and top space constraints of square views to low value (750 or lower than 1000). Default priority value is 1000.

In Interface Builder, You can set the priority in Attribute Inspector.

for Landscape

Create constraints in code for landscape mode.

The constraints should have higher priority than portraits. Keep the constraints in array and add or remove constraints in viewWillLayoutSubviews method of UIViewController.

Test code in following.

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *view1; // square 1
@property (weak, nonatomic) IBOutlet UIView *view2; // square 2
@property (weak, nonatomic) IBOutlet UIView *view3; // square 3 

@end    

@implementation ViewController{

        NSMutableArray *_constraintsList;

    }

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.


        _constraintsList = [NSMutableArray new];


        // constraints for Landscape mode  
        // this constraints has 1000 priority. (default value) 
        // please modify offset value (20 or 40) to match your case. 

        NSDictionary *views = @{@"view1": self.view1, @"view2": self.view2,@"view3": self.view3};

        [_constraintsList addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[view1]-20-[view2]-20-[view3]"
                                                                                      options:0 metrics:nil
                                                                                        views:views]];
        [_constraintsList addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-40-[view2]" options:0 metrics:nil views:views]];


         [_constraintsList addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-40-[view3]" options:0 metrics:nil views:views]];


    }



    -(void)viewWillLayoutSubviews{

        [super viewWillLayoutSubviews];


        UIInterfaceOrientation currentOrientation = [UIApplication sharedApplication].statusBarOrientation;

        if(currentOrientation == UIInterfaceOrientationPortrait){

            // in portrait mode. 
            // new constraints is not necessary. 
            [self.view removeConstraints:_constraintsList];


        }else if(currentOrientation == UIInterfaceOrientationLandscapeLeft){

            // for landscape mode
            // add new constraints. then auto layout adjust view to fit new higher constraints 
            [self.view addConstraints:_constraintsList];


        }

    }
soulpark
  • 96
  • 4
  • Interesting - so the idea is to set/constrain the way it should normally look, with lower priority, and then if it's in landscape mode basically add new constraints with higher priority and it should adhere to the new constraints? I should probably look this up, but what does @"V:|-40-[view2]" do? I'd imagine V stands for vertical, and is it 40 pixels of spacing between the first element and the 2nd? – NullHypothesis Jul 14 '14 at 13:19
  • yes. you know exactly what I said. @"v:|-40-[view2]" is just example code. I just wanna show you that you need to add vertical constraints of square2 and square3. It could be better to set vertical constraints of square2 and square3 to equal vertical center of square1. – soulpark Jul 14 '14 at 13:35
  • thanks - hey just out of curiosity, (not trying to say someone is more correct, etc, just interested in your opinion) what do you think about what this guy did? he got it working using storyboard only: https://github.com/yas375/ExampleApp/tree/39b921b373b14c928d073c0b2451bcfbf79682df the source post comes from: http://stackoverflow.com/questions/19364430/how-can-i-use-constraints-autolayout-with-to-specify-a-different-layout-on-lands?rq=1 Would you say it's a less robust solution, perhaps? Or just an alternate way of achieving what I was talking about? Thanks for your help! – NullHypothesis Jul 14 '14 at 13:42
  • I forgot this. @v:|-40-[view2]. v means vertical. | means superview of view2. In my test case, it's view of uiviewcontroller. I added square views to view of viewcontroller in interface Builder. 40 means y offset between superview of view2 and view2. – soulpark Jul 14 '14 at 13:43
  • @user3379785 I've checked the solution you linked. I think it's a good solution but little bit difficult to understand what programmer intend to. In your case, relationship among squares is important to draw a view. It's not necessary to know screen size of landscape mode to calculate of squares position. but in storyboard case, you should know size of landscape mode to calculate it. For your information, the solution using priority is also useful to animate views in auto layout. – soulpark Jul 14 '14 at 15:36
  • Hey soul park I know this isn't supposed to be a chat forum but I wanted to say thank you for providing this solution - in the end it was really intuitive for me and I completely get it now!!! Is this a common approach that people do? the code was really straight forward. – NullHypothesis Jul 15 '14 at 01:24