AutoLayout: center two views center to superview's center

Deadly 提交于 2019-12-13 17:17:25

问题


I want to create custom UIView with UIImageView and UILabel. UIImageView should be automatically resizable to image size and UILabel should be automatically resizable vertically to text content.

Could you help me to create constraints. I need to center of dynamic views: UIIamgeView and UILabel should be in center of my custom view.


回答1:


I usually achieve this by using some sort of containerView.

By doing this, I can center the containerView within self.view (or wherever you want to centre it) and then constrain content (imageView and label) within it.

Here is a working code sample that I quickly made.

//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];

For a test, I constrained the image view to 100pt x 50pt and gave it a red background, the label was 50pt x 100pt with a green background and the contentView has a blue background. Here is what i got:

For convenience, i use the UIView-Autolayout category by jrturton but you could easily convert the above code to use raw NSLayoutConstraints if you wanted.

The category can be found here: UIView-Autolayout
Documentation can be found here: Cocoadocs




回答2:


The image view will automatically tend to resize with its content. It will, however, get larger or smaller if other constraints push or pull on it with higher priority. So, set its content hugging and compression resistance priorities to high.

The label would normally tend to be one line and extend its width to fix all of its content on that line. You can set its preferredMaxLayoutWidth to have it tend to wrap to multiple lines at the specified width. Again, you should set the content hugging and compression resistance priorities to high.

It's not clear if you want the container to size itself to fit the content or if you want the content to be in the center with a potentially variable distance to the container edges. It's also not clear if you want the image above the label, below it, leading it, or trailing it.

Making the container size itself to the content is relatively straightforward. I'm guessing you want to know how to center the image and label within a larger view. I would embed the image and label into a view which closely contains them. Then you can set up constraints to center that inner container view in the outer container.


So, suppose there's a containerView, an imageView, and a label. I propose adding an innerContainerView used to keep the image and label, together, centered vertically in the containerView. The constraints would look like:

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)-|

So: the inner container view vertically hugs the image and the label, which are separated by the standard distance. The inner container is at least as wide as the image view and the label. But, it tries (at a low priority) to be as small as possible. That makes it horizontally hug the wider of the image view and the label. Then, the inner container is centered vertically within the outer container. The outer container must be at least as tall as the inner container (or, conversely, if it can't, it will force the inner container to be shorter, which will force the image view or label to be shorter; that will be resisted by their compression resistance; to resolve ambiguity, set their resistances to have different priorities).

I used 0 for that last constraint, but you might want to use a different value.

You would probably want to repeat the last two constraints for the horizontal direction, too, although you may prefer something different there. I'm mostly addressing your goal about the vertically centering.

I expressed these constraints in pseudo-code, but you should be able to set them all up with IB.



来源:https://stackoverflow.com/questions/24403359/autolayout-center-two-views-center-to-superviews-center

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!