以编程方式设置约束与在IB中设置它们有何不同?

9
我还不熟悉iOS中的自动布局技术。理论上,我非常喜欢这个概念,但是我试图完成最简单的事情时却感到很头痛。我猜测自己仍然缺乏一些基本原则。我正在尝试通过实践学习,并在实际应用程序之前掌握基础知识,因此我创建了非常简单的测试项目。以下是一个最简单的项目,但它并没有按预期工作。首先是能够正常工作的部分。在IB中,我添加了一个视图来填满整个视图控制器,XCode会自动将约束设置为顶部、底部、前导和尾随以及间距为0。在完成IB后,它可以像预期的那样工作:enter image description here接着旋转成下面这样:enter image description here 太棒了!现在我正在试图用代码做同样的事情:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIView *redView = [[UIView alloc] initWithFrame:self.view.bounds];
redView.backgroundColor = [UIColor redColor];
[self.view addSubview:redView];

redView.translatesAutoresizingMaskIntoConstraints = NO;

[self.view addConstraint:[NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0f constant:0.0f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.0f constant:0.0f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0f constant:0.0f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.0f constant:0.0f]];
}

除了单页应用程序的默认代码外,以上就是所有的代码。

我尝试以编程方式模拟与IB相同的东西,并运行以上代码,在旋转后得到以下结果:

enter image description here

为什么相同的约束会导致不同的结果?可能是我错过了一些非常简单和尴尬的东西。求助!

3个回答

7

我知道这个问题已经有一段时间了,但是我认为你在约束条件方面存在混淆。我已经修改了你的代码如下,现在它可以按预期填充屏幕:

       UIView *redView = [[UIView alloc] initWithFrame:self.view.bounds];
redView.backgroundColor = [UIColor redColor];
[self.view addSubview:redView];

redView.translatesAutoresizingMaskIntoConstraints = NO;

[self.view addConstraint:[NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0f constant:0.0f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.0f constant:0.0f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1.0f constant:0.0f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0f constant:0.0f]];

您原本将尾部约束设置为底部(实际上,尾部是右侧而不是底部),并将顶部约束与左侧(前导)相关联。


6
以下是我的做法:

以下是我的做法:

[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[redView]|"
                                                                  options:0
                                                                  metrics:nil
                                                                    views:NSDictionaryOfVariableBindings(redView)]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[redView]|"
                                                                  options:0
                                                                  metrics:nil
                                                                    views:NSDictionaryOfVariableBindings(redView)]];

在IB中的自动布局可能会令人头疼,我发现熟悉Visual Format Language比使用constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:方法要简单得多。

谢谢!那个有效了(在V:| [redView]中添加丢失的|之后……但是为什么我的其他代码不起作用???它难道不等同于IB显示的吗??? - user1459524
是的,我那里缺了一个管道符号。已修复。说实话,我不知道。我找到了VFL并且没有再寻找其他的AutoLayout需求。 - geraldWilliam
大家好。6个月后我遇到了同样的问题,但我想直接使用mycontroller.view来解决,而不是在mycontroller.view内部使用一个视图。但它什么也没做! - shinyuX
@AmitBattan 是的,你可以在这个链接中找到相关信息:https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/VisualFormatLanguage.html - Raptor
@shinyuX 我知道这是老问题了(希望你已经解决了),为了使用代码中设置的这些约束条件,你需要将 translatesAutoresizingMaskIntoConstraints 设置为 NO - Raptor

1

使用“顶部”和“底部”代替“前导”和“尾随”。请注意,在原始帖子中您混淆了这些术语。前导和尾随似乎会让人们感到困惑!


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