当前位置: 首页 > 知识库问答 >
问题:

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

郎弘壮
2023-03-14

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

我设置了以下约束:

红色视图:

  • 超级视图的顶部空间:0
  • 落后和领先空间到超级视图:0
  • 高度等于:100

蓝色视图:

  • 顶部空间到红色视图:0
  • 落后和领先空间到超级视图: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 布局需要] 甚至 [自我.视图集需要更新约束][自我.blueView 设置需要更新约束],但这没有任何区别。

奇怪的是,如果我从蓝色视图中删除标签,一切都会按预期运行。只要我再次添加它,蓝色视图就保持不变。标签是否有任何约束没有区别。

共有2个答案

通飞尘
2023-03-14

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

徐昕
2023-03-14

这是一个完整的实现:

@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
 类似资料:
  • 我必须在屏幕上显示一个带有多个“开关”控件iPhone弹出窗口。并分别通过打开/关闭操作在弹出窗口上添加和删除子视图。有关情况的更好说明,请参见下面 就像上面一样,当“添加邮件”开关为“ON”时,弹出视图必须再次增加高度,再添加两个子视图。最后看起来像这样, 就是这样。我正在通过我的应用程序使用自动布局,这是我感到困惑的地方。我知道我可以删除弹出窗口,每次都可以再删除一个新的弹出窗口,但这似乎是新

  • 我有一个具有两个垂直约束的视图,一个1:1的纵横比坐标系和一个中心对齐,因此它会根据屏幕的高度自动调整大小。现在,这个视图以UIImageViews的形式填充了一系列较小的子视图。我希望这些图像视图能够自动调整与超级视图成比例的大小,但我不知道如何做到这一点。我在superview中尝试了无数种约束,但都以一团糟而告终。有什么想法吗?

  • 我有3个子视图(、、

  • 我有一列多个具有固有大小的动态子视图(图像、标签等)。如何让超级视图适应自动布局中的子视图? 如果子视图不是动态的,我会将最大的子视图的前沿/后沿约束到超级视图。像这样 我以为我能够与前缘对齐,然后将尾随约束设置为

  • 我遇到了自动布局的问题,似乎无法找到应该很容易实现的答案。 我有以下视图层次结构: 标签上的前导/尾随限制使它们在更薄的设备上更高(iPhone 4s vs iPhone 6)。 为了让UIScrollview正常工作,我需要在UIScrollView内部设置UIView的高度约束,以避免出现“不明确的高度”警告。 但在iPhone 4s上运行时,UIView不够高,无法容纳它的子视图。 到目前为

  • 问题内容: 我必须在Android中构建更复杂的自定义视图。最终布局应如下所示: 但是,我只想在XML文件中定义它(不定义SomeView,SomeOtherView等): 这在Android中可行吗?如果可以,那么最干净的方法是什么?我想到的可能解决方案是“重写addView()方法”和“删除所有视图并在以后再次添加它们”,但是我不确定该走哪条路… 在此先感谢您的帮助!:) 问题答案: 绝对有可