为啥关闭 translatesAutoResizingMasks 会导致自动布局崩溃,抱怨我需要调用 [super layoutSubviews]?

Posted

技术标签:

【中文标题】为啥关闭 translatesAutoResizingMasks 会导致自动布局崩溃,抱怨我需要调用 [super layoutSubviews]?【英文标题】:Why does turning off translatesAutoResizingMasks cause an autolayout crash complaining that I need to call [super layoutSubviews]?为什么关闭 translatesAutoResizingMasks 会导致自动布局崩溃,抱怨我需要调用 [super layoutSubviews]? 【发布时间】:2013-09-27 23:47:06 【问题描述】:

我有一个 UITableView,在 UIBuilder 中定义了一个标题。我遇到了自动调整掩码与我的约束冲突的错误,所以我开始四处寻找,直到找到原因。

不幸的是,修复似乎是导致崩溃的原因。当我以编程方式关闭 setTranslatesResizingMasks 时,不会发生冲突的布局错误(因为它已修复,或者因为它永远没有机会),而是我遇到了崩溃:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Auto Layout still required after executing -layoutSubviews. UITableView's implementation of -layoutSubviews needs to call super.'

我尝试了其他一些线程(如this one)关于使用方法调配来“修补” UITableViewCell 的建议(我继续使用 UITableVIew 进行操作),但没有帮助。

编辑:

这里有一些可以实现的示例代码。因为我需要能够在运行时改变视图,所以它必须通过代码创建,而不是故事板。

请注意,如果我在自己的视图中添加表头,一切正常;当我尝试将其作为表格的标题视图嵌入时,事情就开始爆炸了。我要么关闭 tableHeader 视图的 translateAutoresizingMaskIntoConstraints 以避免冲突,要么在使用自动布局时遇到冲突(它破坏的约束导致我的一些控件神秘地消失)。

self.palletTagField=[[UITextField alloc] init];
[self.palletTagField setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.palletTagField setDelegate:self];
[self.palletTagField setBorderStyle:UITextBorderStyleRoundedRect];

UIButton *addButton=[UIButton buttonWithType:UIButtonTypeContactAdd];
[addButton addTarget:self
              action:@selector(addPalletTagButtonPressed)
    forControlEvents:UIControlEventTouchUpInside];
[addButton setTranslatesAutoresizingMaskIntoConstraints:NO];

UIView *tableHeader=[[UIView alloc] init];
[tableHeader setTranslatesAutoresizingMaskIntoConstraints:NO];//Problem line
[tableHeader addSubview:self.palletTagField];
[tableHeader addSubview:addButton];
[tableHeader addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-[field]-[button]-|"
                                                                    options:NSLayoutFormatAlignAllCenterY
                                                                    metrics:nil
                                                                      views:@@"field":self.palletTagField,
                                                                              @"button":addButton]];
[tableHeader addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[field]-|"
                                                                    options:kNilOptions
                                                                    metrics:nil
                                                                      views:@@"field": self.palletTagField]];

UITableView *palletTable=[[UITableView alloc] init];
[palletTable registerClass:[UITableViewCell class] forCellReuseIdentifier:@"palletTagCell"];
[palletTable setEditing:YES];
self.palletTagTable=palletTable;
palletTable.tableHeaderView=tableHeader;
[palletTable setTranslatesAutoresizingMaskIntoConstraints:NO];
[palletTable setDataSource:self];
[palletTable setDelegate:self];

[self.contentView addSubview:palletTable];

[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[pallets]-|"
                                                                         options:kNilOptions
                                                                         metrics:nil
                                                                           views:@@"pallets":palletTable]];
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[last]-[pallets(>=400)]"
                                                                         options:kNilOptions
                                                                         metrics:nil
                                                                           views:@@"last": lastObject,
                                                                                   @"pallets":palletTable]];

调试器的示例输出:

[ANONYMIZED][31422:70b] 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:0x8f77810 H:|-(NSSpace(20))-[UITextField:0x8f6ad70]   (Names: '|':UIView:0x8f77650 )>",
    "<NSLayoutConstraint:0x8f77860 H:[UITextField:0x8f6ad70]-(NSSpace(8))-[UIButton:0x8f77500]>",
    "<NSLayoutConstraint:0x8f778d0 H:[UIButton:0x8f77500]-(NSSpace(20))-|   (Names: '|':UIView:0x8f77650 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x8fad160 h=--& v=--& H:[UIView:0x8f77650(0)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x8f77860 H:[UITextField:0x8f6ad70]-(NSSpace(8))-[UIButton:0x8f77500]>

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.
[ANONYMIZED][31422:70b] 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:0x8f77940 V:|-(NSSpace(20))-[UITextField:0x8f6ad70]   (Names: '|':UIView:0x8f77650 )>",
    "<NSLayoutConstraint:0x8f77980 V:[UITextField:0x8f6ad70]-(NSSpace(20))-|   (Names: '|':UIView:0x8f77650 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x8fad1c0 h=--& v=--& V:[UIView:0x8f77650(0)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x8f77980 V:[UITextField:0x8f6ad70]-(NSSpace(20))-|   (Names: '|':UIView:0x8f77650 )>

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.

【问题讨论】:

你找到解决方案了吗? @testing 不记得了,抱歉。 【参考方案1】:

此线程可能重复:Why am I getting a "Auto Layout still required after executing -layoutSubviews" error every time my app launches now?

将 'translatesAutoresizingMaskIntoConstraints' 设置为 YES 会影响将视图的自动调整大小约束转换为布局引擎可以满足的布局约束。

这里的问题是您指定不应该发生这种情况,而是创建了一堆约束来描述视图的布局。由于 UITableView 不会创建这些约束,因此“仍然需要自动布局”。

发布正在破坏的初始约束以及一些详细说明布局约束设置的代码可能对您很有用。

【讨论】:

很遗憾,目前我没有现成的相关代码。 我设法再次遇到问题,在上面添加了一些示例代码。

以上是关于为啥关闭 translatesAutoResizingMasks 会导致自动布局崩溃,抱怨我需要调用 [super layoutSubviews]?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 UINavigationController 上关闭 UIAlertController 调用关闭?

为啥或为啥不在 C++ 中使用 memset? [关闭]

为啥输出总是零? [关闭]

为啥我们必须输入 vim ~/.vimrc 而为啥不只输入 vim ~.vimrc? [关闭]

为啥Redis要关闭THP?

为啥没有 IntegerArrayInputStream 类? [关闭]