使用 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
的中心,dynamicView
在parentView
的范围内。
我的第一次尝试是设置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 来恢复