在代码中创建与topLayoutGuide和bottomLayoutGuide相关的自动布局约束

65

苹果公司有关创建视图和布局指南之间的自动布局约束的文档只展示了一个使用VFL的例子。

是否有一种在编程中不使用VFL(例如使用NSLayoutConstraint的其他API或类似方法)来创建这些约束的方式?

(注:我特别想要在代码中完成这个问题,不是在Interface Builder中完成。我也不想将计算出的length 设置为约束的静态常量,而是想要一种可以自动调整位置的约束,以响应布局指南长度的变化。)


什么是VFL?链接已经失效了... - Nicolas Miari
4个回答

93

如果您想要将UIButton放置在UIViewController.topLayoutGuide下方20个点,则可以按以下方式创建NSLayoutConstraint

[NSLayoutConstraint constraintWithItem:self.button
                             attribute:NSLayoutAttributeTop
                             relatedBy:NSLayoutRelationEqual
                                toItem:self.topLayoutGuide
                             attribute:NSLayoutAttributeBottom
                            multiplier:1.0
                              constant:20.0];

iOS 9还可以通过以下方式创建NSLayoutConstraint

[self.button.topAnchor constraintEqualToAnchor:self.topLayoutGuide.bottomAnchor
                                      constant:20.0];

9
你的想法部分正确。你的代码确实可行,但是为了让它起作用,不需要使用 NSLayoutAttributeBaseline。如果你要将其固定到 topLayoutGuide,则 NSLayoutAttributeBottom 同样适用(当然,当固定到 bottomLayoutGuide 时应该使用 NSLayoutAttributeTop)。不管怎样...我之前认为尝试过这种方法,但没有成功...可能是我搞错了什么。 - smileyborg
感谢@smileyborg。我还更新了我的答案,包括新的iOS 9 API。 - Jamie McDaniel

6
补充@JamieMcDaniel的答案,Swift + iOS9版本为:
self.button.topAnchor
    .constraintEqualToAnchor( self.topLayoutGuide.bottomAnchor ).active = true

不要忘记.active = true这一部分,否则约束条件将无法自动触发。


3

补充一下@Jamie McDaniel的建议,如果不是显而易见的话,您需要添加他建议创建的约束条件:

NSLayoutConstraint *buttonTopConstraint = [NSLayoutConstraint constraintWithItem:self.button
                                 attribute:NSLayoutAttributeTop
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:self.topLayoutGuide
                                 attribute:NSLayoutAttributeBottom
                                multiplier:1.0
                                  constant:20.0];
[self.view addConstraint:buttonTopConstraint];

3
这是我创建的一个代码片段,你需要将所有子视图嵌入到一个容器视图中,并将该容器视图添加到xib文件中。这个代码片段会移除容器视图与其父视图之间的约束,并添加一个到topLayoutGuide的上方约束,使得界面看起来像是在iOS6系统中实现的。如果你想要实现类似的效果,这可能会对你有所帮助。
//This should be added before the layout of the view
- (void) adaptToTopLayoutGuide {
    //Check if we can get the top layoutguide
    if (![self respondsToSelector:@selector(topLayoutGuide)]) {
        return;
    }
    //tankView is a contaner view
    NSArray * array = [self.tankView referencingConstraintsInSuperviews]; //<--For this method get the Autolayout Demistified Book Sample made by Erica Sadun
    [self.view removeConstraints:array];
    NSArray * constraintsVertical = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[topLayoutGuide]-0-[tankView]|" options:0 metrics:nil views:@{@"tankView": self.tankView, @"topLayoutGuide":self.topLayoutGuide}];
    [self.view addConstraints:constraintsVertical];
    NSArray * constraintsHorizontal = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[tankView]|" options:0 metrics:nil views:@{@"tankView": self.tankView}];
    [self.view addConstraints:constraintsHorizontal];

}

抱歉,但这并没有解答我的具体问题。 - smileyborg
1
VLF是使用自动布局的最佳选择,我找不到任何不使用它的具体原因,我只是建议提供一段代码,可以帮助您指向正确的方向.. 如果您想考虑一下。 - Andrea
2
VFL 有其自身的优缺点。个人而言,我并不是它的铁杆支持者,这就是为什么我编写了这个针对 UIView 的自动布局类别(https://github.com/smileyborg/UIView-AutoLayout),它解决了比 VFL 更多的用例。我甚至在该项目的 README 中编写了所有自动布局方法(包括 VFL)的优缺点。 - smileyborg
非常有趣...我已经阅读了自述文件,并同意您的观点,但我所缺少的是使用案例,我的意思是为什么要在一般布局中使用普通布局,而不是VLF?性能?还是其他原因? - Andrea
“Normal layout” 是什么意思? - smileyborg
显示剩余5条评论

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