以编程方式使用自动布局约束
我正在尝试以编程方式在我的iOS应用中使用autolayout。
我有一个简单的视图控制器,带有这个初始化代码
I'm trying to use autolayout in my iOS app programmatically. I have a simple view controller with this init code
UIView *innerView = [[UIView alloc] initWithFrame:self.view.bounds];
UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button1 setFrame:CGRectMake(50, 50, 150, 50)];
[button1 setTitle:@"button1" forState:UIControlStateNormal];
UIButton *button2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button2 setFrame:CGRectMake(250, 50, 150, 50)];
[button2 setTitle:@"button2" forState:UIControlStateNormal];
[innerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[button1][button2(==button1)]|" options:NSLayoutFormatAlignAllBaseline metrics:0 views:NSDictionaryOfVariableBindings(button1, button2)]];
[innerView addSubview:button1];
[innerView addSubview:button2];
[self.view addSubview:innerView];
但是当我试图运行它时,我收到了这个错误:
But when I'm trying to run this, I'm getting this error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse constraint format:
Unable to interpret '|' character, because the related view doesn't have a superview
|[button1][button2(==button1)]|
^'
它出了什么问题?
当我尝试删除 constraintsWithVisualFormat
中的管道时,我收到此警告:
And when I'm trying to remove pipes in constraintsWithVisualFormat
, I'm getting this warning:
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:0x716be10 h=--& v=--& UIRoundedRectButton:0x71631f0.midX == + 325>",
"<NSAutoresizingMaskLayoutConstraint:0x7169940 h=--& v=--& H:[UIRoundedRectButton:0x715fb80(150)]>",
"<NSAutoresizingMaskLayoutConstraint:0x7169860 h=--& v=--& UIRoundedRectButton:0x715fb80.midX == + 125>",
"<NSLayoutConstraint:0x7164cd0 UIRoundedRectButton:0x71631f0.width == UIRoundedRectButton:0x715fb80.width>",
"<NSLayoutConstraint:0x7164940 H:[UIRoundedRectButton:0x715fb80]-(0)-[UIRoundedRectButton:0x71631f0]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7164940 H:[UIRoundedRectButton:0x715fb80]-(0)-[UIRoundedRectButton:0x71631f0]>
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.
由于此原因,我的约束根本没有效果。
我做错了什么?
And as result of this, my constraints have no effect at all. What am I doing wrong?
你有三个问题:
首先,您需要在您的按钮子视图上选择基于布局的约束
First, you need to opt-in to layout based contraints on your both your button subviews
[button1 setTranslatesAutoresizingMaskIntoConstraints:NO];
[button2 setTranslatesAutoresizingMaskIntoConstraints:NO];
这将消除NSAutoresizingMaskLayoutConstraint错误。现在,您可以了解布局约束的内容。
This will get rid of the NSAutoresizingMaskLayoutConstraint errors. Now you can get onto what's going on with your layout constraints.
其次,在添加之前,您必须 addSubview
限制。在button1和button2是innerview的子视图之前,你在innerView上调用 addContraints
。
Second, you have to addSubview
before adding the constraints. You are calling addContraints
on innerView before button1 and button2 are subviews of innerview.
第三,您应指定(尽管文档表明它是可选的)布局字符串是纵向还是水平。 @ H:| [按钮1] [BUTTON2(==按钮1)] |
。您还需要一个垂直约束,如 @V:[button1] |
,这会将button1与 innerview $ c $的底部对齐c>因为你在按钮上有对齐的基线,按钮2将会跟随。
Third, you should specify (although the docs indicate it is optional) whether the layout string is vertical or horizontal. @"H:|[button1][button2(==button1)]|"
. You will also want a vertical constraint like @"V:[button1]|"
which would align button1 to the bottom of innerview
and because you have aligned baselines on the buttons, button2 will follow.