为什么关闭 translatesAutoResizingMasks 会导致自动布局崩溃并提示需要调用 [super layoutSubviews]?

4

我有一个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.'

我尝试了一些其他线程的建议(如这个),使用方法交换来“修补”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
@testing 不记得了,抱歉。 - RonLugge
1个回答

2
可能是此线程的重复:为什么每次启动我的应用程序时都会出现“执行-layoutSubviews后仍需要自动布局”错误? 将“translatesAutoresizingMaskIntoConstraints”设置为YES的效果是将视图的自动调整大小约束转换为可以由布局引擎满足的布局约束。
问题在于,您指定不应发生这种情况,而是创建了一堆约束来描述视图的布局。由于UITableView不创建这些约束,因此仍然需要自动布局。
您可以发布导致破坏的初始约束以及有关布局约束设置的一些代码,这可能会对您有所帮助。

很不幸,此时我没有相关的代码可供使用。 - RonLugge
我成功地重新遇到了这个问题,并在上面添加了一些示例代码。 - RonLugge

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接