基于总行的动态表高度的Autolayout +约束

首先,这不是关于动态细胞的高度。 所以不要混淆。

我有一个场景,我创造了三张牌

  1. 明细卡:显示位置的具体细节
  2. 图表卡:根据选择显示不同的图表
  3. 更多细节卡:卡片显示更多细节

以下是上述卡片的屏幕:

在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

查看上述屏幕的层次结构:

  • 调节器
    • 滚动型
    • 卡 – 1
    • 卡-2
    • Card-3 <—-我们对这张卡感兴趣
      • 自定义视图
        • 的TableView

所以我在这里展示了最后一张卡片的限制,以上所有卡片都是完美的! 并且没有约束歧义或警告。

我们来看看代码:

首先将Card-3添加到ScrollView此处chartBox是Card-2, bottomBox是Card-3

 [self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[chartBox(200)]-(10)-[bottomBox]" options:0 metrics:nil views:@{@"bottomBox" : self.bottomBox, @"chartBox" : self.chartBox}]]; // Below constraint pin to increase content-size [self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[bottomBox]-(10)-|" options:0 metrics:nil views:@{@"bottomBox" : self.bottomBox}]]; [self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[bottomBox]-(10)-|" options:0 metrics:nil views:@{@"bottomBox" : self.bottomBox}]]; 

第二步将CustomView添加到Card-3这里bluePrintView是CustomView

 _bluePrintView = [[BluePrintView alloc] init]; self.bluePrintView.translatesAutoresizingMaskIntoConstraints = NO; [self.bottomBox addSubview:self.bluePrintView]; [self.bottomBox addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[bluePrintView]|" options:0 metrics:nil views:@{@"bluePrintView":self.bluePrintView}]]; [self.bottomBox addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[bluePrintView]|" options:0 metrics:nil views:@{@"bluePrintView":self.bluePrintView}]]; CGRect screenRect = [[UIScreen mainScreen] bounds]; CGFloat screenWidth = screenRect.size.width - 20; NSDictionary *metrices = @{@"width" : [NSNumber numberWithFloat:screenWidth]}; [self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(10)-[bottomBox(width)]" options:0 metrics:metrices views:@{ @"bottomBox": self.bottomBox}]]; 

第三CustomViewTableViewCustomView

 self.tableView.tableFooterView = [[UIView alloc] init]; [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[tableView]|" options:0 metrics:nil views:@{@"tableView":self.tableView}]]; [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[tableView]|" options:0 metrics:nil views:@{@"tableView":self.tableView}]]; // Height constraint CGFloat viewHeight = self.bounds.size.height; self.tableHeightConstraint = [NSLayoutConstraint constraintWithItem:self.tableView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:viewHeight]; [self addConstraint:self.tableHeightConstraint]; [self.tableView addObserver:self forKeyPath:@"contentSize" options:0 context:NULL]; 

在观察者方法中,我将更新tableHeightConstraint约束。

 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { self.tableHeightConstraint.constant = self.tableView.contentSize.height; [self.tableView setNeedsLayout]; [self.tableView layoutIfNeeded]; } 

在尝试所有可能性后,最终在这里。 约束警告。

 ( "", "", "", "" ) Will attempt to recover by breaking constraint  

我通过删除|来解决了这些警告 来自[tableView] (通过删除底部约束到superView),但是tableView没有得到欲望高度。

任何想法如何获得完整的tableView高度没有任何约束警告。

PS所有视图都是由代码创建的,没有XIB没有Storyboard布局。 iOS 9.2

我没有在约束设置中看到任何错误。

您可能会看到此UITemporaryLayoutHeight约束,因为您在视图生命周期中过早添加了contentSize观察者( [self.tableView addObserver:self forKeyPath:@"contentSize" options:0 context:NULL] ),这会触发[self.tableView layoutIfNeeded]

尝试在viewDidLoad添加观察者,在视图控制器的dealloc中删除它; 或者在viewWillAppear ,并在viewWillDisappear中将其删除以获取viewWillDisappear