使用自动布局动态添加子视图时,如何调整父视图的大小

3
我需要在iPhone屏幕上展示一个带有多个“开关”控件的弹出视图,并且根据开/关操作在弹出视图上添加和移除子视图。为了更好地说明情况,请参考以下内容:
上面的弹出视图首先出现在用户点击按钮时。该弹出视图必须始终保持在屏幕中央,最初添加联系人开关将处于关闭状态。当打开下面的子视图时,必须将其添加到弹出视图上,同时保持弹出视图在屏幕中央并根据子视图增加弹出视图的高度。
与上述类似,当“添加邮件”开关打开时,弹出视图将再次增加两个子视图的高度。最后看起来像这样:
就是这样。我在整个应用程序中都使用自动布局,这就是我感到困惑的地方。我知道每次可以删除弹出视图并添加一个新的,但这似乎是一种比较初级的选项。那么是否有任何简单的方法可以使用自动布局动态添加子视图并扩展其父视图?我已经看到了许多关于UILabel的问题,并且根据其内在内容大小进行了工作,但仍无法在这种特定情况下获得任何想法。任何帮助将不胜感激。祝你编码愉快。

在原始情况下,你的约束条件是什么样子? - Andrew Monshizadeh
目前我还没有设置任何约束条件,因为我实际上不知道如何做到这一点,正如你所看到的,我必须动态添加子视图,所以我不知道如何使用自动布局来实现它。正如它所说,即使我隐藏了子视图,计算子视图时仍然会考虑其约束条件。 - Rameswar Prasad
请查看我的答案,了解如何使用布局约束来实现您想要的效果。 - Andrew Monshizadeh
2个回答

4
这可以通过普通布局约束来实现,无需手动约束容器视图的高度,然后更新该约束的常数值。具体方法是,根据最下面的子视图的底部约束容器视图的高度。
然后在您的视图控制器中引用此约束。
现在您可以编写如下的视图控制器,它将在容器视图的底部添加一个新的子视图,并自动更新容器视图的高度。
#import "ViewController.h"

@interface ViewController ()

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomConstraint;
@property (weak, nonatomic) IBOutlet UIButton *addButton;
@property (weak, nonatomic) IBOutlet UIView *containerView;
@property (nonatomic, weak) UIView *lastView;

@end

@implementation ViewController

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

    self.lastView = self.addButton;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)addButtonTapped:(id)sender {
    UIView *newView = [[UIView alloc] initWithFrame:CGRectZero];
    newView.translatesAutoresizingMaskIntoConstraints = NO;
    newView.backgroundColor = [UIColor redColor];
    [newView addConstraint:[NSLayoutConstraint constraintWithItem:newView
                                                       attribute:NSLayoutAttributeHeight
                                                       relatedBy:NSLayoutRelationEqual
                                                          toItem:nil
                                                       attribute:NSLayoutAttributeNotAnAttribute
                                                      multiplier:1.0
                                                         constant:35]];

    [self.containerView addSubview:newView];
    [self.containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[lastView]-(14)-[newView]"
                                                                     options:NSLayoutFormatAlignAllCenterX
                                                                     metrics:nil
                                                                        views:@{@"lastView" : self.lastView, @"newView" : newView}]];
    [self.containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(10)-[newView]-(10)-|"
                                                                     options:NSLayoutFormatAlignmentMask
                                                                     metrics:nil
                                                                        views:@{@"newView":newView}]];

    [self.containerView removeConstraint:self.bottomConstraint];
    self.bottomConstraint = [NSLayoutConstraint constraintWithItem:self.containerView
                                                         attribute:NSLayoutAttributeBottom
                                                         relatedBy:NSLayoutRelationEqual
                                                            toItem:newView
                                                         attribute:NSLayoutAttributeBottom
                                                        multiplier:1.0
                                                          constant:14];
    [self.containerView addConstraint:self.bottomConstraint];

    self.lastView = newView;
}
@end

将这些加在一起,你应该得到以下行为。 enter image description here

0
您可以将视图的出口高度约束设置为元素的相应值。

你的意思是我必须为所有子视图以及容器弹出视图采取高度约束IBOutlets,并动态更改它们,首先保持不需要的子视图的约束为“零”,然后在需要显示时更改它们,并使用一些小的扩展动画来更改容器视图的高度约束吗? - Rameswar Prasad
你不需要三个子视图,只需一个即可。隐藏文本字段,然后操作将使textField.hidden = NO并设置_heightCOnstraint = 60.00; - mokiSRB
好的,明白了。谢谢。 - Rameswar Prasad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接