简体   繁体   English

iOS AutoLayout旋转时更改位置

[英]IOS AutoLayout Change position on Rotation

I wanted to sent one container below the other on portrait and side by side on landscape. 我想将一个容器纵向放在另一个容器下面,并将其横向放置在一起。 Is it possible with just auto layout? 仅使用自动布局是否可能? I know i can do it programmatically, just wondering if it is possible to do it from the layout. 我知道我可以通过编程方式做到这一点,只是想知道是否有可能从布局上做到这一点。

Like This: 像这样:

期望的行为

Yep, I think there is going to be a little code though. 是的,我认为虽然会有一些代码。 So the I believe the 2 constraints involved here are horizontal spacing and vertical spacing (Editor -> Pin -> Horizontal/Vertical). 因此,我相信这里涉及的2个约束是水平间距和垂直间距(编辑器->固定->水平/垂直)。

Arrange A and B in the portrait layout, select both of the elements, and add both of those constraints. 在纵向布局中排列A和B,选择两个元素,然后添加两个约束。 Create IBOutlets to both of these constraints in the header file (just like you would a label, button, etc) 在头文件中为这两个约束创建IBOutlet(就像您将标签,按钮等一样)

You can then change the values of these constraints in the "didRotateFromInterfaceOrientation" delegate method (constraint_variable_name.constant = 0;). 然后可以在“ didRotateFromInterfaceOrientation”委托方法中更改这些约束的值(constraint_variable_name.constant = 0;)。 Let me know if any of this is unclear or you need me to elaborate on any part of it. 如果其中任何一个不清楚,请让我知道,或者您需要我详细说明。

Well didRotateFromInterfaceOrientation is not the preferred way to do these kind of things with iOS 8. I would suggest you to take a look at traitCollection and view controller methods associated with it. 不错,didRotateFromInterfaceOrientation不是使用iOS 8进行此类操作的首选方法。我建议您看一下traitCollection并查看与之关联的控制器方法。 The trick here is to install horizontal constraint or vertical constraint when UIViewController method viewWillTransitionToSize:withTransitionCoordinator : trigger. 这里的技巧是在UIViewController方法viewWillTransitionToSize:withTransitionCoordinator :trigger时安装水平约束或垂直约束。

Here is the way I did it, 这是我的方法

@interface ViewController ()

@property (nonatomic, weak) UIView *aContainerView;
@property (nonatomic, weak) UIView *bContainerView;

@property (nonatomic, strong) NSArray *horizontalOrientationConstraints;
@property (nonatomic, strong) NSArray *verticalOrientationConstraints;

@end

@implementation ViewController

#pragma mark - Getters

- (NSArray *)horizontalOrientationConstraints
{
    if (!_horizontalOrientationConstraints) {
        NSLayoutConstraint *equalWidthConstraints = [NSLayoutConstraint constraintWithItem:self.aContainerView
                                                                                 attribute:NSLayoutAttributeWidth
                                                                                 relatedBy:NSLayoutRelationEqual
                                                                                    toItem:self.bContainerView
                                                                                 attribute:NSLayoutAttributeWidth
                                                                                multiplier:1.0
                                                                                  constant:0];

        NSArray *vConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[aContainerView][bContainerView]|"
                                                                        options:NSLayoutFormatAlignAllTop | NSLayoutFormatAlignAllBottom
                                                                        metrics:nil views:@{@"aContainerView": self.aContainerView, @"bContainerView": self.bContainerView}];
        NSArray *hConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[aContainerView]|"
                                                                        options:0
                                                                        metrics:nil
                                                                          views:@{@"aContainerView": self.aContainerView}];
        NSArray *constraints = [vConstraints arrayByAddingObjectsFromArray:hConstraints];
        _horizontalOrientationConstraints = [constraints arrayByAddingObject:equalWidthConstraints];

    }
    return _horizontalOrientationConstraints;
}


- (NSArray *)verticalOrientationConstraints
{
    if (!_verticalOrientationConstraints) {
        NSLayoutConstraint *equalHeightConstraints = [NSLayoutConstraint constraintWithItem:self.aContainerView
                                                                                  attribute:NSLayoutAttributeHeight
                                                                                  relatedBy:NSLayoutRelationEqual
                                                                                     toItem:self.bContainerView
                                                                                  attribute:NSLayoutAttributeHeight
                                                                                 multiplier:1.0
                                                                                   constant:0];


        NSArray *vConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[aContainerView][bContainerView]|"
                                                                        options:NSLayoutFormatAlignAllLeft | NSLayoutFormatAlignAllRight
                                                                        metrics:nil views:@{@"aContainerView": self.aContainerView, @"bContainerView": self.bContainerView}];
        NSArray *hConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[aContainerView]|"
                                                                        options:0
                                                                        metrics:nil
                                                                          views:@{@"aContainerView": self.aContainerView}];
        NSArray *constraints = [vConstraints arrayByAddingObjectsFromArray:hConstraints];
        _verticalOrientationConstraints = [constraints arrayByAddingObject:equalHeightConstraints];

    }
    return _verticalOrientationConstraints;
}

#pragma mark - 


- (void)viewDidLoad
{
    [super viewDidLoad];

    UIView *aContainerView = [self viewWithLabelText:@"A" andBackgroundColor:[UIColor yellowColor]];
    UIView *bContainerView = [self viewWithLabelText:@"B" andBackgroundColor:[UIColor greenColor]];

    [self.view addSubview:aContainerView];
    [self.view addSubview:bContainerView];

    self.aContainerView = aContainerView;
    self.bContainerView = bContainerView;

    CGSize viewSize = self.view.bounds.size;

    if (viewSize.width > viewSize.height) {
        [NSLayoutConstraint activateConstraints:self.horizontalOrientationConstraints];
    } else {
        [NSLayoutConstraint activateConstraints:self.verticalOrientationConstraints];
    }
}

- (UIView *)viewWithLabelText:(NSString *)text andBackgroundColor:(UIColor *)color
{
    UIView *aContainerView = [[UIView alloc] init];
    aContainerView.backgroundColor = [UIColor blackColor];
    aContainerView.translatesAutoresizingMaskIntoConstraints = NO;

    UIView *aView = [[UIView alloc] init];
    aView.translatesAutoresizingMaskIntoConstraints = NO;
    aView.backgroundColor = color;

    UILabel *aLabel = [[UILabel alloc] init];
    aLabel.translatesAutoresizingMaskIntoConstraints = NO;
    aLabel.text = text;
    aLabel.font = [UIFont systemFontOfSize:80];

    [aView addSubview:aLabel];

    [aContainerView addSubview:aView];


    NSLayoutConstraint *centerXConstraints = [NSLayoutConstraint constraintWithItem:aView
                                                                          attribute:NSLayoutAttributeCenterX
                                                                          relatedBy:NSLayoutRelationEqual
                                                                             toItem:aLabel
                                                                          attribute:NSLayoutAttributeCenterX
                                                                         multiplier:1.0
                                                                           constant:0];
    NSLayoutConstraint *centerYConstraints = [NSLayoutConstraint constraintWithItem:aView
                                                                          attribute:NSLayoutAttributeCenterY
                                                                          relatedBy:NSLayoutRelationEqual
                                                                             toItem:aLabel
                                                                          attribute:NSLayoutAttributeCenterY
                                                                         multiplier:1.0
                                                                           constant:0];
    [aContainerView addConstraints:@[centerXConstraints, centerYConstraints]];


    NSString *hConstraintsFormat = @"V:|-10-[view]-10-|";
    NSString *vConstraintsFormat = @"H:|-10-[view]-10-|";

    [aContainerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:hConstraintsFormat
                                                                                options:0
                                                                                metrics:nil
                                                                                  views:@{@"view": aView}]];
    [aContainerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vConstraintsFormat
                                                                                options:0
                                                                                metrics:nil
                                                                                  views:@{@"view": aView}]];

    return aContainerView;
}



 - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    NSArray *constraintsToDeactivate;
    NSArray *constraintsToActivate;

    if (size.width > size.height) {
        constraintsToActivate = self.horizontalOrientationConstraints;
        constraintsToDeactivate = self.verticalOrientationConstraints;
    } else {
        constraintsToActivate = self.verticalOrientationConstraints;
        constraintsToDeactivate = self.horizontalOrientationConstraints;
    }

    [NSLayoutConstraint deactivateConstraints:constraintsToDeactivate];
    [NSLayoutConstraint activateConstraints:constraintsToActivate];
    [self.view layoutIfNeeded];
}

@end

Here is how it looks for both the orientations, 这是两个方向的外观,

在此处输入图片说明

在此处输入图片说明

For iOS7, you basically do the same thing. 对于iOS7,您基本上会做同样的事情。 Instead of overriding viewWillTransitionToSize: you should rather override willAnimateRotationToInterfaceOrientation:duration:. 而不是覆盖viewWillTransitionToSize:您应该覆盖willAnimateRotationToInterfaceOrientation:duration:。 Then you add or remove the constraint inside the method, 然后在方法内部添加或删除约束,

@interface ViewController ()

@property (nonatomic, weak) UIView *aContainerView;
@property (nonatomic, weak) UIView *bContainerView;

@property (nonatomic, assign) BOOL touchExited;
@property (nonatomic, assign) NSUInteger count;
@property (nonatomic, weak) NSTimer *countChangeTimer;
@property (nonatomic, weak) UIButton *theCountButton;

@property (nonatomic, strong) NSArray *horizontalOrientationConstraints;
@property (nonatomic, strong) NSArray *verticalOrientationConstraints;

@end

@implementation ViewController

#pragma mark - Getters

- (NSArray *)horizontalOrientationConstraints
{
    if (!_horizontalOrientationConstraints) {
        NSLayoutConstraint *equalWidthConstraints = [NSLayoutConstraint constraintWithItem:self.aContainerView
                                                                                 attribute:NSLayoutAttributeWidth
                                                                                 relatedBy:NSLayoutRelationEqual
                                                                                    toItem:self.bContainerView
                                                                                 attribute:NSLayoutAttributeWidth
                                                                                multiplier:1.0
                                                                                  constant:0];

        NSArray *vConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[aContainerView][bContainerView]|"
                                                                        options:NSLayoutFormatAlignAllTop | NSLayoutFormatAlignAllBottom
                                                                        metrics:nil views:@{@"aContainerView": self.aContainerView, @"bContainerView": self.bContainerView}];
        NSArray *hConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[aContainerView]|"
                                                                        options:0
                                                                        metrics:nil
                                                                          views:@{@"aContainerView": self.aContainerView}];
        NSArray *constraints = [vConstraints arrayByAddingObjectsFromArray:hConstraints];
        _horizontalOrientationConstraints = [constraints arrayByAddingObject:equalWidthConstraints];

    }
    return _horizontalOrientationConstraints;
}


- (NSArray *)verticalOrientationConstraints
{
    if (!_verticalOrientationConstraints) {
        NSLayoutConstraint *equalHeightConstraints = [NSLayoutConstraint constraintWithItem:self.aContainerView
                                                                                  attribute:NSLayoutAttributeHeight
                                                                                  relatedBy:NSLayoutRelationEqual
                                                                                     toItem:self.bContainerView
                                                                                  attribute:NSLayoutAttributeHeight
                                                                                 multiplier:1.0
                                                                                   constant:0];


        NSArray *vConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[aContainerView][bContainerView]|"
                                                                        options:NSLayoutFormatAlignAllLeft | NSLayoutFormatAlignAllRight
                                                                        metrics:nil views:@{@"aContainerView": self.aContainerView, @"bContainerView": self.bContainerView}];
        NSArray *hConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[aContainerView]|"
                                                                        options:0
                                                                        metrics:nil
                                                                          views:@{@"aContainerView": self.aContainerView}];
        NSArray *constraints = [vConstraints arrayByAddingObjectsFromArray:hConstraints];
        _verticalOrientationConstraints = [constraints arrayByAddingObject:equalHeightConstraints];

    }
    return _verticalOrientationConstraints;
}

#pragma mark -

- (void)invalidateTimer
{
    if (self.countChangeTimer) {
        [self.countChangeTimer invalidate];
    }
}


- (void)viewDidLoad
{
    [super viewDidLoad];

    UIView *aContainerView = [self viewWithLabelText:@"A" andBackgroundColor:[UIColor yellowColor]];
    UIView *bContainerView = [self viewWithLabelText:@"B" andBackgroundColor:[UIColor greenColor]];

    [self.view addSubview:aContainerView];
    [self.view addSubview:bContainerView];
    self.aContainerView = aContainerView;
    self.bContainerView = bContainerView;

    CGSize viewSize = self.view.bounds.size;

    if (viewSize.width > viewSize.height) {
        [self.view addConstraints:self.horizontalOrientationConstraints];
    } else {
        [self.view addConstraints:self.verticalOrientationConstraints];
    }
}

- (UIView *)viewWithLabelText:(NSString *)text andBackgroundColor:(UIColor *)color
{
    UIView *aContainerView = [[UIView alloc] init];
    aContainerView.backgroundColor = [UIColor blackColor];
    aContainerView.translatesAutoresizingMaskIntoConstraints = NO;

    UIView *aView = [[UIView alloc] init];
    aView.translatesAutoresizingMaskIntoConstraints = NO;
    aView.backgroundColor = color;

    UILabel *aLabel = [[UILabel alloc] init];
    aLabel.translatesAutoresizingMaskIntoConstraints = NO;
    aLabel.text = text;
    aLabel.font = [UIFont systemFontOfSize:80];

    [aView addSubview:aLabel];

    [aContainerView addSubview:aView];


    NSLayoutConstraint *centerXConstraints = [NSLayoutConstraint constraintWithItem:aView
                                                                          attribute:NSLayoutAttributeCenterX
                                                                          relatedBy:NSLayoutRelationEqual
                                                                             toItem:aLabel
                                                                          attribute:NSLayoutAttributeCenterX
                                                                         multiplier:1.0
                                                                           constant:0];
    NSLayoutConstraint *centerYConstraints = [NSLayoutConstraint constraintWithItem:aView
                                                                          attribute:NSLayoutAttributeCenterY
                                                                          relatedBy:NSLayoutRelationEqual
                                                                             toItem:aLabel
                                                                          attribute:NSLayoutAttributeCenterY
                                                                         multiplier:1.0
                                                                           constant:0];
    [aContainerView addConstraints:@[centerXConstraints, centerYConstraints]];


    NSString *hConstraintsFormat = @"V:|-10-[view]-10-|";
    NSString *vConstraintsFormat = @"H:|-10-[view]-10-|";

    [aContainerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:hConstraintsFormat
                                                                                options:0
                                                                                metrics:nil
                                                                                  views:@{@"view": aView}]];
    [aContainerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vConstraintsFormat
                                                                                options:0
                                                                                metrics:nil
                                                                                  views:@{@"view": aView}]];

    return aContainerView;
}

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration{
    NSArray *constraintsToDeactivate;
    NSArray *constraintsToActivate;

        if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
            constraintsToActivate = self.horizontalOrientationConstraints;
            constraintsToDeactivate = self.verticalOrientationConstraints;
        } else {
            constraintsToActivate = self.verticalOrientationConstraints;
            constraintsToDeactivate = self.horizontalOrientationConstraints;
        }
        [self.view removeConstraints:constraintsToDeactivate];
        [self.view addConstraints:constraintsToActivate];

}

@end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM