【问题标题】:Autolayout fails when setting label constraint to 0 in UITableView header在 UITableView 标头中将标签约束设置为 0 时自动布局失败
【发布时间】:2014-08-29 06:12:07
【问题描述】:

我正在尝试使用 usual 删除标签的方法并让自动布局调整所有内容。 How to change label constraints during runtime。但是,我是在 UITableView header 中进行的。

当我设置其中一个标签的高度约束时:

self.labelAHeight.constant = 0;

结果是:

Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want. Try this: (1)
look at each constraint and try to figure out which you don't expect; (2) find the code that added 
the unwanted constraint or constraints and fix it. (Note: If you're seeing 
NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the 
UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0xb0faad0 V:[UILabel:0xb0fa830(0)]>",
    "<NSLayoutConstraint:0xb0772a0 V:[UILabel:0xb077300(58)]>",
    "<NSLayoutConstraint:0xb076cc0 V:|-(0)-[UILabel:0xb0fa830]   (Names: '|':UIView:0xb077660 )>",
    "<NSLayoutConstraint:0xb076c90 V:[UILabel:0xb077300]-(0)-|   (Names: '|':UIView:0xb077660 )>",
    "<NSLayoutConstraint:0xb076c00 V:[UILabel:0xb0fa830]-(0)-[UILabel:0xb077300]>",
    "<NSAutoresizingMaskLayoutConstraint:0xb06f030 h=--& v=--& V:[UIView:0xb077660(119)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0xb0772a0 V:[UILabel:0xb077300(58)]>

Break on objc_exception_throw to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> 
may also be helpful.

我尝试过[self.labelA setTranslatesAutoresizingMaskIntoConstraints:NO],但没有帮助。

我尝试了[self.table.tableHeaderView setTranslatesAutoresizingMaskIntoConstraints:NO]*** Assertion failure in -[UITableView layoutSublayersOfLayer:], /SourceCache/UIKit_Sim/UIKit-2935.137/UIView.m:8794 崩溃。可能,我在错误的地方执行此操作(就在设置约束常量之前)。

约束变化发生在哪里似乎并不重要,例如viewDidLoad,或按钮处理程序。

看起来好像标题想要达到某个高度(&lt;NSAutoresizingMaskLayoutConstraint:0xb06f030 h=--&amp; v=--&amp; V:[UIView:0xb077660(119)]&gt; 基于其内容)并且如果内容发生更改,自动布局会变得非常不愉快。

谁能帮助调试或建议如何解决它? (我尝试过 Instruments,但对添加和删除的所有约束感到困惑......)

【问题讨论】:

    标签: ios uitableview autolayout constraints tableheader


    【解决方案1】:

    以下是部分答案。可以防止上面的约束问题,但是,我还没有找到如何使表的其余部分随着表头大小的变化而移动。

    1) 在情节提要中设置表头的 translatesAutoresizingMaskIntoConstraints = NO。

    2) 既然自动调整大小的掩码没有产生约束,就在标题上设置约束。

    - (void)viewDidLoad {
        [super viewDidLoad];
    
        [self.table addConstraint:
                 [NSLayoutConstraint constraintWithItem:self.table.tableHeaderView
                                              attribute:NSLayoutAttributeWidth
                                              relatedBy:NSLayoutRelationEqual
                                                 toItem:self.table
                                              attribute:NSLayoutAttributeWidth
                                             multiplier:1
                                               constant:0]];
        [self.table addConstraint:
                 [NSLayoutConstraint constraintWithItem:self.table.tableHeaderView
                                              attribute:NSLayoutAttributeTop
                                              relatedBy:NSLayoutRelationEqual
                                                 toItem:self.table
                                              attribute:NSLayoutAttributeTop
                                             multiplier:1
                                               constant:0]];
    }
    

    将标签A的高度约束的常数设置为零的结果是:

    之前:

    之后(可以看到顶部标签已经消失,但表格行并没有上移到表头底部):

    我已经验证了标题视图实际上已经降低了它的高度。

    我已经在标题、表格、视图上尝试过setNeedsLayoutsetNeedsDisplay。我试过beginUpdatesendUpdates 来设置约束常数。我试过reloadData。但没有任何效果。

    我怀疑表格在表头和单元格之间没有约束。

    如果有人有任何想法,我很乐意听到。

    编辑

    3) 可以使用以下内容重新绘制表格:

    self.labelAHeight.constant = 0;
    [self performSelector:@selector(reloadHeader) withObject:nil afterDelay:0];
    
    //    [self.table.tableHeaderView setNeedsUpdateConstraints];
    //    
    //    [UIView animateWithDuration:0.3f animations:^{
    //        [self.table.tableHeaderView layoutIfNeeded];
    //    }];
    

    - (void) reloadHeader {
    //    [self.table beginUpdates];
        self.table.tableHeaderView = self.table.tableHeaderView;
    //    [self.table endUpdates];
    }
    

    取消注释上面的行会尝试为更改设置动画,但标题的动画和表格的其余部分并没有严格联系在一起,因此标题和表格之间可能会出现间隙。

    仍然不完美,但正在接近。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-22
      • 2017-12-24
      • 2014-03-24
      • 1970-01-01
      相关资源
      最近更新 更多