AutoLayout:将两个视图中心置于superview的中心

时间:2014-06-25 08:08:07

标签: ios objective-c constraints autolayout

我想使用UIViewUIImageView创建自定义UILabelUIImageView应自动调整为图片大小,UILabel应自动调整为文本内容的垂直大小。

你能帮我创建约束吗?我需要以动态视图为中心:UIIamgeViewUILabel应位于我的自定义视图的中心。

2 个答案:

答案 0 :(得分:0)

图片视图会自动调整其内容的大小。但是,如果其他约束以更高的优先级推动或拉动它,它将变大或变小。因此,将其内容拥抱和压缩阻力优先级设置为高。

标签通常倾向于一条线并延伸其宽度以固定该线上的所有内容。您可以设置其preferredMaxLayoutWidth以使其倾向于以指定的宽度换行到多行。同样,您应该将内容拥抱和压缩阻力优先级设置为高。

目前尚不清楚您是希望容器的大小适合内容,还是希望内容位于中心,与容器边缘的距离可能有所变化。还不清楚你是想要将图像放在标签上方,下方,引导它还是尾随它。

将容器大小本身设置为内容相对简单。我猜你想知道如何在更大的视图中居中图像和标签。我会将图像和标签嵌入到一个紧密包含它们的视图中。然后,您可以设置约束以将内部容器视图置于外部容器中。


因此,假设有containerViewimageViewlabel。我建议添加innerContainerView用于保持图像和标签一起垂直居中于containerView。约束看起来像:

V:|[imageView]-[label]|
|-(>=0)-[imageView]-(>=0)-|
|-(>=0)-[label]-(>=0)-|
[innerContainerView(==0@50)|
[NSLayoutConstraint constraintWithItem:innerContainerView
                             attribute:NSLayoutAttributeCenterY
                             relatedBy:NSLayoutRelationEqual
                                toItem:containerView
                             attribute:NSLayoutAttributeCenterY
                            multiplier:1
                              constant:0]
V:|-(>=0)-innerContainerView-(>=0)-|

所以:内部容器视图垂直拥抱图像和标签,它们以标准距离分开。内部容器至少与图像视图和标签一样宽。但是,它尝试(在低优先级)尽可能小。这使它横向拥抱图像视图和标签的更宽广。然后,内部容器在外部容器内垂直居中。外部容器必须至少与内部容器一样高(或者相反,如果不能,则会迫使内部容器变短,这将迫使图像视图或标签更短;这将被抵抗通过它们的抗压性;为了解决模糊性,将它们的阻力设置为具有不同的优先级。)

我使用0代表最后一个约束,但你可能想要使用不同的值。

你可能也希望重复水平方向的最后两个约束,尽管你可能更喜欢那些不同的东西。我主要是关于垂直居中的目标。

我在伪代码中表达了这些约束,但你应该能够用IB设置它们。

答案 1 :(得分:0)

我通常使用某种containerView来实现这一点。

通过执行此操作,我可以将containerView置于self.view(或您想要居中的任何位置)的中心,然后将内容(imageView和标签)限制在其中。

这是我快速制作的工作代码示例。

//create a container view to hold the centered content
UIView *containerView = [UIView autoLayoutView];


//create our content
UIImageView *imageView = [UIImageView autoLayoutView];
UILabel *label = [UILabel autoLayoutView];

//configure the imageView and label
//...
//Note: The imageView and label should be able to satisfy their own width and height.

//add the content to our container
[containerView addSubview:imageView];
[containerView addSubview:label];

//pin the left and right of our content to the container with a flexible constraint
[imageView pinAttribute:NSLayoutAttributeLeft toAttribute:NSLayoutAttributeLeft ofItem:containerView withConstant:0.0 relation:NSLayoutRelationGreaterThanOrEqual];
[label pinAttribute:NSLayoutAttributeLeft toAttribute:NSLayoutAttributeLeft ofItem:containerView withConstant:0.0 relation:NSLayoutRelationGreaterThanOrEqual];
[imageView pinAttribute:NSLayoutAttributeRight toAttribute:NSLayoutAttributeRight ofItem:containerView withConstant:0.0 relation:NSLayoutRelationLessThanOrEqual];
[label pinAttribute:NSLayoutAttributeRight toAttribute:NSLayoutAttributeRight ofItem:containerView withConstant:0.0 relation:NSLayoutRelationLessThanOrEqual];

//also center the content horizontally within the container
[imageView centerInContainerOnAxis:NSLayoutAttributeCenterX];
[label centerInContainerOnAxis:NSLayoutAttributeCenterX];

//pin the content vertically
[imageView pinToSuperviewEdges:JRTViewPinTopEdge inset:0.0];
[imageView pinAttribute:NSLayoutAttributeBottom toAttribute:NSLayoutAttributeTop ofItem:label withConstant:0.0];
[label pinToSuperviewEdges:JRTViewPinBottomEdge inset:0.0];


//add the container to self.view
[self.view addSubview:containerView];

//center our container view
[containerView centerInContainerOnAxis:NSLayoutAttributeCenterX];
[containerView centerInContainerOnAxis:NSLayoutAttributeCenterY];

对于测试,我将图像视图限制为100pt x 50pt并给它一个红色背景,标签为50pt x 100pt,绿色背景,contentView为蓝色背景。这是我得到的:

enter image description here

为方便起见,我使用了jrturton的UIView-Autolayout类别,但如果你愿意,可以轻松转换上面的代码以使用原始的NSLayoutConstraints。

可在此处找到类别:UIView-Autolayout
可以在此处找到文档:Cocoadocs

相关问题