使用 NSLayoutConstraint 将大型 UIView 居中

Posted

技术标签:

【中文标题】使用 NSLayoutConstraint 将大型 UIView 居中【英文标题】:Center a large UIView using NSLayoutConstraint 【发布时间】:2013-10-08 09:24:02 【问题描述】:

我是使用 Autolayouts 的新手,即使这是我的第一次尝试。无论我用它做什么,我都会以白屏结束。这是我的尝试。

我有一个UIView,让我说一个框架(60, 154, 200, 200)parentView。它是self.view 的子视图。

然后我有一个动态视图,比如框架(0, 0, 260, 100)dynamicView 和框架(15, 25, 230, 50)label,这是dynamicView 的子视图。

当我将dynamicView 作为子视图添加到parentView 时,它超出了parentView 的范围。所以,我想调整dynamicView 及其子项(label) 的大小,使其位置位于parentView 的中心,dynamicViewparentView 的范围内。

我的第一次尝试是设置clipsToBounds,它在 Xcode5、ios7 中不起作用。所以下一个选项是使用NSLayoutConstraint 来实现这一点。我对此一无所知。我欢迎你的想法。

【问题讨论】:

【参考方案1】:

我将解决作为 parentView 问题一部分的 dyanmicView,然后让您从那里开始

首先:如果您是动态创建视图,那么您就可以开始了,但如果您是从情节提要中创建的,则必须将其与父级分离,然后重新附加它..这就是你摆脱它以前的 NSConstraints (通常是故事板引入的)可能与你的新的冲突的方法。

您还必须将 setTranslatesAutoresizingMaskIntoConstraints 设置为 NO b/c,这也会干扰您的 nsconstraints。

我通常像这样执行最后两个步骤,使用mapObjectsUsingBlock 使创建约束的整个繁琐过程更加愉快和自然:

    [@[view_1, view_2, /../, view_n] mapObjectsApplyingBlock:^(UIView *view) 
        [view removeFromSuperview];
        [view setTranslatesAutoresizingMaskIntoConstraints:NO];
        [view setHidden:NO];
        [superView addSubview:view];
    ];

那么在应用 nsconstraints 之前,您必须确保要应用约束的视图已经附加到它的父级:

[parentView addSubview:dynamicView];

那么你想创建一个绑定字典:

NSDictionary *buttonBindingsDictionary = @ @"parentView" : parentView,
                                            @"dynamicView" : dynamicView;

那么你想使用visual format language添加约束。我在这里也使用mapObjectsUsingBlock(我会用英文解释每个约束):

NSArray *buttonConstraints = [@[@"V:|-[dynamicView(>=200)]-|",
                                @"|-[dynamicView(>=260)]-|",
                                ] mapObjectsUsingBlock:^id(NSString *formatString, NSUInteger idx)
    return [NSLayoutConstraint constraintsWithVisualFormat:formatString options:0 metrics:nil views:buttonBindingsDictionary];
];

V:|-[dynamicView(>=200)]-|表示垂直方向..dynamicView和它的父级之间的上下距离应该相等..还有dynamicView's高度应该不小于200

|-[dynamicView(>=260)]-| 表示横向来说..dyanmicview 和它的父级之间的左右距离应该相等.. 还有dyanmicView's 宽度应该不小于260

注意:您可以自己计算并准确设置 dyanicView 与其父级之间的左/右/下/上距离。这更简单。但有时 nsconstraints搞砸了,我必须自己做。

在这种情况下,它看起来像这样,x 是您想出的距离:

V:|-x-[dynamicView(>=200)]-x-|
|-x-[dynamicView(>=260)]-x-|

那么你必须将约束添加到父视图:

[parentView addConstraints:[buttonConstraints flattenArray]];

请注意,我在这里使用了flatten array,这也是我的库 b/c 中的一种方法,我想为它提供一个单级数组,而不是数组数组。

你可以走了!

注意:我知道这可能无法完美运行.. 但它让您知道该怎么做 + 一些帮助文件。这需要一些练习,你应该看看tutorials 的一些内容。我建议你从使用故事板的nsconstraints 开始(你可以选择一个视图..然后去编辑器> pin>..然后选择一些东西.. 得到一些即时的视觉反馈..您还可以通过选择视图控制器,然后转到属性检查器并在模拟指标下选择不同的大小,立即在情节提要上模拟您的视图在 3.5" 显示与 4.0" 显示中的样子)

花点时间花点时间,但有一件事是肯定的:一旦你去 nsconstraints,你将永远不会回头!完全值得!

附言您也可以使用 nsconstraints animate 视图。以防万一您想知道。

【讨论】:

【参考方案2】:

Auto Layout Constraints 是实现目标的最佳方法。当您在 IB 中选中 Use Autolayout 选项时,会自动添加自动布局约束。

查看本教程,了解有关 iOS6 中自动布局的更多信息 http://www.raywenderlich.com/20881/beginning-auto-layout-part-1-of-2

然后您可以查看此链接以获取 iOS7 中更新的自动布局 http://www.doubleencore.com/2013/09/auto-layout-updates-in-ios-7/

【讨论】:

以上是关于使用 NSLayoutConstraint 将大型 UIView 居中的主要内容,如果未能解决你的问题,请参考以下文章

将实例变量与 NSLayoutConstraint 的视觉格式一起使用是不是有最佳实践?

无法将“NSLayoutConstraint”类型的不可变值作为 inout 参数传递

自动布局警告:将尝试通过在 CollectionView 中打破约束 <NSLayoutConstraint 来恢复

NSLayoutConstraint 将 centerX 约束到 superview 的另一侧

错误的 NSLayoutConstraint 导致黑屏

NSLayoutConstraint - 无法将子视图框架设置为父视图边界