ios 如何在目标 c 中以编程方式添加约束
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35294571/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to add Constraint programmatically in objective c
提问by Crazy Developer
I want to add constraint programmatically and I use below code to add TOP and LEFT constraint.
我想以编程方式添加约束,我使用下面的代码来添加 TOP 和 LEFT 约束。
NSLayoutConstraint *top = [NSLayoutConstraint constraintWithItem:label1
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeTop
multiplier:1
constant:110];
NSLayoutConstraint *left = [NSLayoutConstraint constraintWithItem:label1
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeLeading
multiplier:1
constant:10];
lable1
is added in my view controller. When I add this two constraint in the view like
lable1
添加到我的视图控制器中。当我在视图中添加这两个约束时
[self.view addConstraint:top];
[self.view addConstraint:left];
It gives the error in the consol and constraint does not affect the lable.
它给出了控制台中的错误,并且约束不会影响标签。
2016-02-09 19:36:59.824 testinMRC[99160:313382] 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.
(
"<NSLayoutConstraint:0x7fa5c8738610 V:|-(110)-[UILabel:0x7fa5c8626940'Label'] (Names: '|':UIView:0x7fa5c86267b0 )>",
"<NSIBPrototypingLayoutConstraint:0x7fa5c8628a70 'IB auto generated at build time for view with fixed frame' V:|-(88)-[UILabel:0x7fa5c8626940'Label'] (Names: '|':UIView:0x7fa5c86267b0 )>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7fa5c8738610 V:|-(110)-[UILabel:0x7fa5c8626940'Label'] (Names: '|':UIView:0x7fa5c86267b0 )>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2016-02-09 19:36:59.889 testinMRC[99160:313382] 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.
(
"<NSLayoutConstraint:0x7fa5c87334b0 H:|-(10)-[UILabel:0x7fa5c8626940'Label'] (Names: '|':UIView:0x7fa5c86267b0 )>",
"<NSIBPrototypingLayoutConstraint:0x7fa5c86285c0 'IB auto generated at build time for view with fixed frame' H:|-(188)-[UILabel:0x7fa5c8626940'Label'](LTR) (Names: '|':UIView:0x7fa5c86267b0 )>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7fa5c87334b0 H:|-(10)-[UILabel:0x7fa5c8626940'Label'] (Names: '|':UIView:0x7fa5c86267b0 )>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
Can anyone tell me why this error come? Help me to short out the solution
谁能告诉我为什么会出现这个错误?帮我缩短解决方案
回答by NKorotkov
In your case error clearly states that you have conflicting constraints for your view. Probably because you a trying to add constraints to the view that already has some from Interface Builder. Even if you didn't set up any constrains explicitly IB does provide them for you when it detects that some are missing.
在您的情况下,错误清楚地表明您的视图有冲突的约束。可能是因为您试图向已经有一些来自 Interface Builder 的视图添加约束。即使您没有明确设置任何约束,IB 也会在检测到某些约束缺失时为您提供这些约束。
I see in comments you've mentioned that you want to do everything programmatically.In that case take a look at piece of code:
我在评论中看到你提到你想以编程方式完成所有事情。在这种情况下,请看一段代码:
- (void)viewDidLoad {
[super viewDidLoad];
UIView *view = [UIView new];
view.backgroundColor = [UIColor redColor];
[view setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.view addSubview:view];
NSLayoutConstraint *left = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1 constant:100];
NSLayoutConstraint *top = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1 constant:100];
NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:50];
NSLayoutConstraint *width = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:50];
[self.view addConstraints:@[left, top]];
[view addConstraints:@[height, width]];
}
It's pretty self-explanatory. As you can see I had to add width and height constraints to the view, because only left and top doesn't fully describe it's position.
这是不言自明的。正如您所看到的,我必须为视图添加宽度和高度约束,因为只有 left 和 top 不能完全描述它的位置。
Result:
结果:
I encourage you to try out Visual Format Language. Same result can be achieved with much less code. This code leads to the very same result:
我鼓励您尝试使用 Visual Format Language。可以用更少的代码实现相同的结果。此代码导致非常相同的结果:
NSArray *horizontal = [NSLayoutConstraint constraintsWithVisualFormat:@"|-100-[view(50)]" options:0 metrics:nil views:@{@"view" : view}];
NSArray *vertical = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-100-[view(50)]" options:0 metrics:nil views:@{@"view" : view}];
[self.view addConstraints:vertical];
[self.view addConstraints:horizontal];
Let me know if this helped. Cheers.
如果这有帮助,请告诉我。干杯。
回答by J?rn Buitink
The problem is not your code, it is the IB auto generated at build time for view with fixed frame
message:
问题不在于您的代码,而在于IB auto generated at build time for view with fixed frame
消息:
Interface Builder automatically generates constraints for you if you don't add them yourself. You could avoid it by either
如果您不自己添加约束,Interface Builder 会自动为您生成约束。您可以通过以下任一方式避免它
- Select the nib or storyboard in the Project Navigator, go to the File Inspector and uncheck
Use Auto Layout
.
- 在项目导航器中选择笔尖或故事板,转到文件检查器并取消选中
Use Auto Layout
。
or
或者
- Add some constraints in Interface Builder and set them to
remove at build time
.
- 在 Interface Builder 中添加一些约束并将它们设置为
remove at build time
.
回答by Arjay Waran
It looks like you have conflicting layout constraints. A constraint was most likely set up in storyboard and you are trying to add a constraint programmatically that directly conflicts with it.
看起来您有冲突的布局约束。一个约束很可能是在故事板中设置的,而您正试图以编程方式添加一个直接与其冲突的约束。
It looks like you are trying to move a UIView out of the way after an action occurs. I.E press a button and move a happy face picture from the middle of the screen to the top left corner.
看起来您正在尝试在操作发生后将 UIView 移开。IE 按下按钮,将一张笑脸图片从屏幕中间移动到左上角。
Adding and removing constraints directly in code can be a HUGE headache with code bloat, unit testing and warnings filling up your console.
直接在代码中添加和删除约束可能会让人头疼,代码膨胀、单元测试和警告填满了你的控制台。
It might be a better idea to create the main UIView in storyboard and have a hidden placeholder UIView that holds all the constraints you want the UIView to have after you press the button. Then you can switch out all the constraints programmatically for those UIViews. So the view you want to modify will have the position, width and height of the placeholder and the place holder will have the position and height of the view you want to modify.
在故事板中创建主 UIView 并有一个隐藏的占位符 UIView 可能是一个更好的主意,该占位符 UIView 包含您在按下按钮后希望 UIView 具有的所有约束。然后,您可以以编程方式为这些 UIView 切换出所有约束。所以你要修改的视图会有占位符的位置、宽度和高度,占位符会有你要修改的视图的位置和高度。
This way you will never have this error while changing the layout constraints programmatically because any errors will be caught by the storyboard.
这样,您在以编程方式更改布局约束时永远不会出现此错误,因为故事板会捕获任何错误。
There's some open source that does this for you in one or two lines of code. (There's some youtube video tutorials in the docs too) https://cocoapods.org/pods/SBP
有一些开源可以在一两行代码中为您完成此操作。(文档中也有一些 youtube 视频教程)https://cocoapods.org/pods/SBP
After installing the cocoapod, your code would look something like this
安装 cocoapod 后,您的代码将如下所示
this would be code inside the view controller with the UIView you want to modify and the placeholder UIView
这将是视图控制器中的代码,其中包含要修改的 UIView 和占位符 UIView
//UIView* viewBeforeChange
//UIView* hiddenViewAfterChange
[self switchViewConst:viewBeforeChange secondView:hiddenViewAfterChange];