在使用自动布局调整同级视图大小时,重新定位UIView,子视图不起作用

时间:2014-09-08 07:58:15

标签: ios cocoa-touch uiview autolayout

我有两个视图,我正在尝试使用自动布局调整大小/重新定位。

enter image description here

我设置了以下约束:

红色视图:

  • 超级视图的顶层空间:0
  • 追踪和引导空间到superview:0
  • 高度等于:100

蓝色视图:

  • 顶部空间到红色视图:0
  • 追踪和引导空间到superview:0
  • 高度等于:100

这两个观点都是self.view的子视图。并且蓝色视图具有UILabel作为子视图(屏幕截图中未显示)。 我想要做的是更改红色视图的大小(使用动画),并使蓝色视图遵循该大小更改:

- (IBAction)resizeButtonPressed:(UIButton*)sender
{
    [UIView animateWithDuration:0.25 animations:^{
        if (sender.selected) {
            self.redViewHeightConstraint.constant = 100; // collapse
        }
        else {
            self.redViewHeightConstraint.constant = 200; // expand
        }
        [self.view layoutIfNeeded];
    }];

    sender.selected = !sender.selected;
}

动画有效,红色视图的大小也会改变。但是,蓝色视图永远不会改变位置,即使它对红色视图的底部有约束。

我尝试添加[self.blueView layoutIfNeeded],甚至同时添加[self.view setNeedsUpdateConstraints][self.blueView setNeedsUpdateConstraints],但这没有任何区别。

奇怪的是,如果我从蓝色视图中删除标签,一切都按预期工作。一旦我再次添加它,蓝色视图保持静止。如果标签有任何限制,则没有区别。

2 个答案:

答案 0 :(得分:0)

我也遇到了同样的问题。 我通过在动画块(CGRect frame = self.label.frame;)之前保存标签的帧来解决它,并在动画块中再次设置标签的帧(self.label.frame = frame;

答案 1 :(得分:0)

这是一个完整的实现:

@interface ViewController ()

@property(nonatomic, strong) NSLayoutConstraint* redViewHeightConstraint;

@end

@implementation ViewController


-  (void)viewDidLoad
{
    [super viewDidLoad];

    UIView* redView = [[UIView alloc] init];
    UIView* blueView = [[UIView alloc] init];

    redView.translatesAutoresizingMaskIntoConstraints = NO;
    blueView.translatesAutoresizingMaskIntoConstraints = NO;

    redView.backgroundColor = [UIColor redColor];
    blueView.backgroundColor = [UIColor blueColor];

    NSDictionary* views = NSDictionaryOfVariableBindings(redView, blueView);

    [self.view addSubview:redView];
    [self.view addSubview:blueView];

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[redView]|"
                                                                      options:0
                                                                      metrics:nil
                                                                        views:views]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[blueView]|"
                                                                      options:0
                                                                      metrics:nil
                                                                        views:views]];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:redView
                                                          attribute:NSLayoutAttributeTop
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:self.view
                                                          attribute:NSLayoutAttributeTop
                                                         multiplier:1
                                                           constant:0]];

    self.redViewHeightConstraint = [NSLayoutConstraint constraintWithItem:redView
                                                                attribute:NSLayoutAttributeHeight
                                                                relatedBy:NSLayoutRelationEqual
                                                                   toItem:nil
                                                                attribute:NSLayoutAttributeNotAnAttribute
                                                               multiplier:0
                                                                 constant:100];

    [self.view addConstraint:self.redViewHeightConstraint];


    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:blueView
                                                          attribute:NSLayoutAttributeTop
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:redView
                                                          attribute:NSLayoutAttributeBottom
                                                         multiplier:1
                                                           constant:0]];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:blueView
                                                          attribute:NSLayoutAttributeHeight
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:nil
                                                          attribute:NSLayoutAttributeNotAnAttribute
                                                         multiplier:0
                                                           constant:100]];

    UILabel* label = [[UILabel alloc] init];
    label.text = @"label";
    label.translatesAutoresizingMaskIntoConstraints = NO;
    [blueView addSubview:label];

    [blueView addConstraint:[NSLayoutConstraint constraintWithItem:label
                                                          attribute:NSLayoutAttributeCenterX
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:blueView
                                                          attribute:NSLayoutAttributeCenterX
                                                         multiplier:1
                                                           constant:0]];

    [blueView addConstraint:[NSLayoutConstraint constraintWithItem:label
                                                         attribute:NSLayoutAttributeCenterY
                                                         relatedBy:NSLayoutRelationEqual
                                                            toItem:blueView
                                                         attribute:NSLayoutAttributeCenterY
                                                        multiplier:1
                                                          constant:0]];

    UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [button addTarget:self
               action:@selector(resizeButtonPressed:)
     forControlEvents:UIControlEventTouchUpInside];
    [button setTitle:@"Expand" forState:UIControlStateNormal];
    [button setTitle:@"Collapse" forState:UIControlStateSelected];
    button.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:button];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:button
                                                          attribute:NSLayoutAttributeTop
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:blueView
                                                          attribute:NSLayoutAttributeBottom
                                                         multiplier:1
                                                           constant:30]];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:button
                                                          attribute:NSLayoutAttributeCenterX
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:self.view
                                                          attribute:NSLayoutAttributeCenterX
                                                         multiplier:1
                                                           constant:0]];



}

- (IBAction)resizeButtonPressed:(UIButton*)sender
{
    [UIView animateWithDuration:0.25 animations:^{
        if (sender.selected) {
            self.redViewHeightConstraint.constant = 100; // collapse
        }
        else {
            self.redViewHeightConstraint.constant = 200; // expand
        }
        [self.view layoutIfNeeded];
    }];

    sender.selected = !sender.selected;
}

@end