基于总行数的动态表高度的自动布局+约束

Autolayout + constraints for dynamic table height based on total rows(基于总行数的动态表高度的自动布局+约束)

本文介绍了基于总行数的动态表高度的自动布局+约束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,这与动态单元格的高度无关.所以不要混淆.

我有一个场景,我创建了三张卡片

I have a scenario in that I created three cards

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

以下是上述卡片的屏幕:

Below are screens for above cards:

以上屏幕的视图层次结构:

View hierarchy for above screens:

  • 控制器
    • 滚动视图
    • 卡 1
    • 卡片 2
    • Card-3 <---- 我们对此卡感兴趣
      • 自定义视图
        • 表格视图

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

        So I'm showing the constraints for last card here, all above card works perfect! and there is no constraints ambiguity or warnings.

        让我们通过代码:

        首先将Card-3添加到ScrollView:这里chartBox是Card-2,bottomBox 是 Card-3

        First Add Card-3 to ScrollView: here chartBox is Card-2 and bottomBox is 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

        Second add CustomView to Card-3: Here bluePrintView is 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}]];
        

        第三次添加TableViewCustomView:

        Third add TableView to CustomView:

        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 约束.

        And in observer method I'll update tableHeightConstraint constraint.

        - (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];
        }
        

        在尝试了所有的可能性之后,这里结束了.约束警告.

        After trying all possibilities end up here. Warnings for constraints.

        (
            "<NSLayoutConstraint:0x7fbeb1e7e8e0 V:|-(0)-[UITableView:0x7fbeb2843000]   (Names: '|':BluePrintView:0x7fbeb1e7ac30 )>",
            "<NSLayoutConstraint:0x7fbeb1e7e700 V:[UITableView:0x7fbeb2843000]-(0)-|   (Names: '|':BluePrintView:0x7fbeb1e7ac30 )>",
            "<NSLayoutConstraint:0x7fbeb1e7e9b0 V:[UITableView:0x7fbeb2843000(480)]>",
            "<NSLayoutConstraint:0x7fbeb1e81a20 '_UITemporaryLayoutHeight' V:[BluePrintView:0x7fbeb1e7ac30(0)]>"
        )
        
        Will attempt to recover by breaking constraint 
        <NSLayoutConstraint:0x7fbeb1e7e700 V:[UITableView:0x7fbeb2843000]-(0)-|   (Names: '|':BluePrintView:0x7fbeb1e7ac30 )>
        

        我通过从 [tableView] 中删除 | 行(通过删除 superView 的底部约束)解决了这些警告,但随后 tableView 没有获得所需的高度.

        I solved these warnings by removing | line from [tableView] (by removing bottom constraint to superView), but then tableView does not get desire height.

        知道如何在没有任何约束警告的情况下获得完整的 tableView 高度.

        Any idea how to get full tableView height with out any constraint warnings.

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

        P.S. All views are created by code, no XIB no Storyboard layout. iOS 9.2

        推荐答案

        我在您的约束设置中没有看到任何错误.

        I did not see any error in your constraints setup.

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

        You may see this UITemporaryLayoutHeight constraint because you added the contentSize observer ([self.tableView addObserver:self forKeyPath:@"contentSize" options:0 context:NULL] ) too soon in your view life cycle, which triggers a [self.tableView layoutIfNeeded].

        尝试在 viewDidLoad 中添加观察者,在 View Controller 的 dealloc 中删除它;或者在您的 viewWillAppear 中,并在 viewWillDisappear 中将其删除.

        Try to add the observer in the viewDidLoad, remove it in dealloc of your View Controller ; Or in your viewWillAppear, and remove it in the viewWillDisappear for exemple.

        这篇关于基于总行数的动态表高度的自动布局+约束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:基于总行数的动态表高度的自动布局+约束

基础教程推荐