在 ViewController 中的两个视图上以编程方式设置自动布局约束

Posted

技术标签:

【中文标题】在 ViewController 中的两个视图上以编程方式设置自动布局约束【英文标题】:Setting auto layout constraints programmatically on two views in ViewController 【发布时间】:2016-05-22 07:22:14 【问题描述】:

我正在尝试在 ViewController 上添加两个 UIView。其中一个是普通的 UIView,另一个是 UITableView。我不太确定如何对它们设置高度约束,这样 UITableView 将具有其内容所需的高度,而其他视图可以根据 UITableView 高度调整自身大小。

下面是我用来设置这些约束的简单草图和代码。

 NSDictionary *views = NSDictionaryOfVariableBindings(_infoView,_infoTableView);

[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"[_infoView]"
                                                                  options:0
                                                                  metrics:nil
                                                                    views:views]];

[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_infoView]-[_infoTableView]"
                                                                  options:0
                                                                  metrics:nil
                                                                    views:views]];

// Width constraint
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.infoView
                                                 attribute:NSLayoutAttributeWidth
                                                 relatedBy:NSLayoutRelationEqual
                                                    toItem:self.view
                                                 attribute:NSLayoutAttributeWidth
                                                multiplier:1.0
                                                  constant:0]];

[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.infoTableView
                                                      attribute:NSLayoutAttributeWidth
                                                      relatedBy:NSLayoutRelationEqual
                                                         toItem:self.view
                                                      attribute:NSLayoutAttributeWidth
                                                     multiplier:1.0
                                                       constant:0]];

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

[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.infoTableView
                                                      attribute:NSLayoutAttributeBottom
                                                      relatedBy:NSLayoutRelationEqual
                                                         toItem:self.view
                                                      attribute:NSLayoutAttributeBottom
                                                     multiplier:1.0
                                                       constant:0]];

任何 cmets / 反馈将不胜感激。 谢谢。

【问题讨论】:

你能画个草图或其他东西向我们展示你希望它们看起来如何吗? ozgur - 添加了草图。 【参考方案1】:

你在正确的轨道上。这里的技巧是您需要将tableView 的高度动态更新为其contentSize.height,以便infoView 知道它应该是垂直扩展还是缩小:

首先,您定义一个包含高度约束的属性:

@property (nonatomic, strong) NSLayoutConstraint *tableViewHeightConstraint;

- (void)viewDidLoad 
  ...
  self.tableViewHeightConstraint = [NSLayoutConstraint constraintWithItem:self.tableView
                                                                attribute:NSLayoutAttributeHeight
                                                                relatedBy:NSLayoutRelationEqual
                                                                   toItem:nil
                                                                attribute:NSLayoutAttributeNotAnAttribute
                                                               multiplier:0.0
                                                                 constant:350.0];

然后你可以在tableView知道它的contentSize之后立即更新高度约束(例如:viewDidAppear:animated

- (void)viewDidAppear:(BOOL)animated 
  [super viewDidAppear:animated];

  self.tableViewHeightConstraint.constant = self.tableView.contentSize.height;
  [self.view layoutIfNeeded];
  

我为您创建了a sample project,以便您可以使用它来更好地了解我打算做什么。

【讨论】:

非常感谢您的解释和示例应用程序。按照您的建议,我的问题已通过添加新的 heightConstraint 得到解决。在查看您的示例代码时,我还注意到您没有使用宽度约束/顶部 - 底部约束。有什么具体原因吗?因为当我将代码修改为那些最低限度的约束时,我的两个视图都消失了。 通知| 当我定义垂直约束时,例如:V:|[infoView]-[tableView]|。它确保子视图将约束到父视图的顶部和底部。同样适用于水平约束,例如 H:|[infoView]|,其中 infoView 的前导和尾随受到约束,因此您不必设置任何宽度约束。

以上是关于在 ViewController 中的两个视图上以编程方式设置自动布局约束的主要内容,如果未能解决你的问题,请参考以下文章

在两个失去值的 ViewController 之间传递 UIImage 数组

将 viewController 视图添加到 UIScrollView

Storyboard - 在 Storyboard 中为同一个 ViewController 创建两个不同的视图

当在相同的 ViewController 下触摸具有相同父视图的两个视图时,iOS 无法获取新的 touchEvent

具有多个行为模型的 ViewController

在调用 viewController 之前调用 ViewController 方法的问题