不使用自动布局的 LayoutConstraints 错误
LayoutConstraints error without using Auto Layout
我没有在故事板中使用自动布局或为此实现任何代码。我有一个 UIAlertController
用于用户登录,但在键盘文本输入期间出现 LayoutConstraints
错误。
重要的是要注意,当我在实际设备上 运行 应用程序时不会发生此错误,例如 iPad,只会在模拟器中发生。
我正在使用 Xcode 版本 10.1 (10B61) 并在 Debug 中放置了一个 UIViewAlertForUnsatisfiableConstraints
断点,它指示了一些约束错误。
单步执行所有断点后,我在控制台中收到此消息:
[LayoutConstraints] 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)
(
"<NSAutoresizingMaskLayoutConstraint:0x60000165fe80 h=--& v=--& UIKeyboardAssistantBar:0x7f922cd1aa30.height == 0 (active)>",
"<NSLayoutConstraint:0x6000016768f0 V:|-(0)-[_UIButtonBarStackView:0x7f922cd1d6e0] (active, names: '|':UIKeyboardAssistantBar:0x7f922cd1aa30 )>",
"<NSLayoutConstraint:0x600001676a80 V:[_UIButtonBarStackView:0x7f922cd1d6e0]-(0)-| (active, names: '|':UIKeyboardAssistantBar:0x7f922cd1aa30 )>",
"<NSLayoutConstraint:0x60000165f340 'UIButtonBar.maximumAlignmentSize' _UIButtonBarButton:0x7f922cf87400.height == UILayoutGuide:0x600000c39260'UIViewLayoutMarginsGuide'.height (active)>",
"<NSLayoutConstraint:0x6000016764e0 'UIView-bottomMargin-guide-constraint' V:[UILayoutGuide:0x600000c39260'UIViewLayoutMarginsGuide']-(9)-| (active, names: '|':_UIButtonBarStackView:0x7f922cd1d6e0 )>",
"<NSLayoutConstraint:0x600001676440 'UIView-topMargin-guide-constraint' V:|-(10)-[UILayoutGuide:0x600000c39260'UIViewLayoutMarginsGuide'] (active, names: '|':_UIButtonBarStackView:0x7f922cd1d6e0 )>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x6000016764e0 'UIView-bottomMargin-guide-constraint' V:[UILayoutGuide:0x600000c39260'UIViewLayoutMarginsGuide']-(9)-| (active, names: '|':_UIButtonBarStackView:0x7f922cd1d6e0 )>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
我煞费苦心地检查了故事板,但没有发现任何自动布局约束。
我在每个 UIView
中实现了代码以禁用约束 [self.view removeConstraints:self.view.constraints];
这可能是 Apple 的错误,因为它不会出现在实际设备上吗?
这是用户提示登录和键盘输入的代码 UIAlertController
:
-(void) promptUserLogin
{
NSString *alertTitle = @"User Login Required";
NSString *alertMessage = @"Enter Email and Password";
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:alertTitle
message:alertMessage
preferredStyle:UIAlertControllerStyleAlert];
[alertController addTextFieldWithConfigurationHandler:^(UITextField *textField)
{
textField.placeholder = @"User Email";
[textField addTarget:self action:@selector(alertTextFieldDidChange:)
forControlEvents:UIControlEventEditingChanged];
}];
[alertController addTextFieldWithConfigurationHandler:^(UITextField *textField)
{
textField.placeholder = @"User Password";
textField.secureTextEntry = YES;
}];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle: @"Cancel"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
{
NSLog(@"Cancel action");
}];
UIAlertAction *okAction = [UIAlertAction actionWithTitle: @"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action)
{
UITextField *login = alertController.textFields.firstObject;
UITextField *password = alertController.textFields.lastObject;
NSLog(@"OK Action");
NSLog(@"Login String: %@",login.text);
NSLog(@"Password String: %@",password.text);
}];
okAction.enabled = NO;
[alertController addAction:cancelAction];
[alertController addAction:okAction];
//[self presentViewController:alertController animated:YES completion:nil];
[self.navigationController presentViewController:alertController animated:YES completion:nil];
}
- (void)alertTextFieldDidChange:(UITextField *)sender
{
UIAlertController *alertController = (UIAlertController *)self.presentedViewController;
if (alertController)
{
UITextField *login = alertController.textFields.firstObject;
UIAlertAction *okAction = alertController.actions.lastObject;
okAction.enabled = login.text.length > 2;
}
}
我认为这与您自己的布局问题无关。它与失败的自动布局约束的 InputAssistantItems(键盘上方)有关。如果您查看自动布局错误中列出的第一个自动调整大小约束,它会引用 UIKeyboardAssistantBar。
关于重现它的方式的更多细节:
使用 UITextField 时,其 inputAssistantItem 将不包含任何自动更正建议(无论是安全文本字段还是自动更正类型设置为 UIAutoCorrectionTypeNo),它打破了 auto-layout 约束(我只能重现它在某些情况下,在 UITextFields 或 resigning/becoming active 之间切换时)。
这发生在两种情况下:
- 文本字段将其自动更正类型设置为 UITextAutoCorrectionTypeNo。
- 文本字段是安全文本字段。
在这两种情况下,居中的 UIButtonBarStackView 都是空的(不包含自动更正建议)。
当您通过将 leading/trailing BarButtonGroups 设置为空数组来禁用 inputAssistantItem 或使用启用了 auto-correction 的文本字段时,问题不存在。
编辑:
只是详细说明一下,我不建议使用上述任何一种替代方法来解决此问题,因为您很可能会在引用登录后通过安全文本字段看到它。相反,我的建议是忽略警告,如果您认为合适,将其报告为错误。
我没有在故事板中使用自动布局或为此实现任何代码。我有一个 UIAlertController
用于用户登录,但在键盘文本输入期间出现 LayoutConstraints
错误。
重要的是要注意,当我在实际设备上 运行 应用程序时不会发生此错误,例如 iPad,只会在模拟器中发生。
我正在使用 Xcode 版本 10.1 (10B61) 并在 Debug 中放置了一个 UIViewAlertForUnsatisfiableConstraints
断点,它指示了一些约束错误。
单步执行所有断点后,我在控制台中收到此消息:
[LayoutConstraints] 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)
(
"<NSAutoresizingMaskLayoutConstraint:0x60000165fe80 h=--& v=--& UIKeyboardAssistantBar:0x7f922cd1aa30.height == 0 (active)>",
"<NSLayoutConstraint:0x6000016768f0 V:|-(0)-[_UIButtonBarStackView:0x7f922cd1d6e0] (active, names: '|':UIKeyboardAssistantBar:0x7f922cd1aa30 )>",
"<NSLayoutConstraint:0x600001676a80 V:[_UIButtonBarStackView:0x7f922cd1d6e0]-(0)-| (active, names: '|':UIKeyboardAssistantBar:0x7f922cd1aa30 )>",
"<NSLayoutConstraint:0x60000165f340 'UIButtonBar.maximumAlignmentSize' _UIButtonBarButton:0x7f922cf87400.height == UILayoutGuide:0x600000c39260'UIViewLayoutMarginsGuide'.height (active)>",
"<NSLayoutConstraint:0x6000016764e0 'UIView-bottomMargin-guide-constraint' V:[UILayoutGuide:0x600000c39260'UIViewLayoutMarginsGuide']-(9)-| (active, names: '|':_UIButtonBarStackView:0x7f922cd1d6e0 )>",
"<NSLayoutConstraint:0x600001676440 'UIView-topMargin-guide-constraint' V:|-(10)-[UILayoutGuide:0x600000c39260'UIViewLayoutMarginsGuide'] (active, names: '|':_UIButtonBarStackView:0x7f922cd1d6e0 )>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x6000016764e0 'UIView-bottomMargin-guide-constraint' V:[UILayoutGuide:0x600000c39260'UIViewLayoutMarginsGuide']-(9)-| (active, names: '|':_UIButtonBarStackView:0x7f922cd1d6e0 )>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
我煞费苦心地检查了故事板,但没有发现任何自动布局约束。
我在每个 UIView
中实现了代码以禁用约束 [self.view removeConstraints:self.view.constraints];
这可能是 Apple 的错误,因为它不会出现在实际设备上吗?
这是用户提示登录和键盘输入的代码 UIAlertController
:
-(void) promptUserLogin
{
NSString *alertTitle = @"User Login Required";
NSString *alertMessage = @"Enter Email and Password";
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:alertTitle
message:alertMessage
preferredStyle:UIAlertControllerStyleAlert];
[alertController addTextFieldWithConfigurationHandler:^(UITextField *textField)
{
textField.placeholder = @"User Email";
[textField addTarget:self action:@selector(alertTextFieldDidChange:)
forControlEvents:UIControlEventEditingChanged];
}];
[alertController addTextFieldWithConfigurationHandler:^(UITextField *textField)
{
textField.placeholder = @"User Password";
textField.secureTextEntry = YES;
}];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle: @"Cancel"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
{
NSLog(@"Cancel action");
}];
UIAlertAction *okAction = [UIAlertAction actionWithTitle: @"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action)
{
UITextField *login = alertController.textFields.firstObject;
UITextField *password = alertController.textFields.lastObject;
NSLog(@"OK Action");
NSLog(@"Login String: %@",login.text);
NSLog(@"Password String: %@",password.text);
}];
okAction.enabled = NO;
[alertController addAction:cancelAction];
[alertController addAction:okAction];
//[self presentViewController:alertController animated:YES completion:nil];
[self.navigationController presentViewController:alertController animated:YES completion:nil];
}
- (void)alertTextFieldDidChange:(UITextField *)sender
{
UIAlertController *alertController = (UIAlertController *)self.presentedViewController;
if (alertController)
{
UITextField *login = alertController.textFields.firstObject;
UIAlertAction *okAction = alertController.actions.lastObject;
okAction.enabled = login.text.length > 2;
}
}
我认为这与您自己的布局问题无关。它与失败的自动布局约束的 InputAssistantItems(键盘上方)有关。如果您查看自动布局错误中列出的第一个自动调整大小约束,它会引用 UIKeyboardAssistantBar。
关于重现它的方式的更多细节:
使用 UITextField 时,其 inputAssistantItem 将不包含任何自动更正建议(无论是安全文本字段还是自动更正类型设置为 UIAutoCorrectionTypeNo),它打破了 auto-layout 约束(我只能重现它在某些情况下,在 UITextFields 或 resigning/becoming active 之间切换时)。
这发生在两种情况下:
- 文本字段将其自动更正类型设置为 UITextAutoCorrectionTypeNo。
- 文本字段是安全文本字段。
在这两种情况下,居中的 UIButtonBarStackView 都是空的(不包含自动更正建议)。
当您通过将 leading/trailing BarButtonGroups 设置为空数组来禁用 inputAssistantItem 或使用启用了 auto-correction 的文本字段时,问题不存在。
编辑:
只是详细说明一下,我不建议使用上述任何一种替代方法来解决此问题,因为您很可能会在引用登录后通过安全文本字段看到它。相反,我的建议是忽略警告,如果您认为合适,将其报告为错误。