Auto Layout (Limitations) Center 2 Side Views in Parent View

I am trying to figure out how to do this using auto layout (iOS6) and restrictions.

Basically, I have my big view, divided into two parts below. Inside these sections (currently in subzones) I have an image and a label. I want to center those on both sides, with variable-length text.

My head is mostly wrapped in a car layout, but I'm not sure if this is the best approach. I tend to think that this is not possible in IB, but is in code.

We continue to try to understand this, but at the same time, here is an example that I am trying to create.

enter image description here

+64
ios iphone autolayout constraints
Feb 07 '13 at 0:48
source share
8 answers

This is what you need?

short labellong label

I did this by adding a view (called viewCenteredInLeftSection ) to your leftSection , and then adding a clock image and a label as subtasks with these limitations:

  • Make viewCenteredInLeftSection CenterX and CenterY equal to its supervision ( leftSection ).
  • Make clockImage top, bottom, and leading edges equal to your supervisor ( viewCenteredInLeftSection ).
  • Make label End viewCenteredInLeftSection equal to its supervision ( viewCenteredInLeftSection ).
  • Make clockImage The final border at a standard distance from the label Leading Edge.

viewCenteredInLeftSection

I have a problem resizing iOS UIViews in Interface Builder, so I made my example for OS X and I was able to do this completely in Interface Builder. If you are having problems creating the above restrictions in Interface Builder, let me know and I will send a code that will create them.

2014-08-26 Edit

Luda , here are the Xcode 5 output and embroidery menus, also available on the Xcode menu bar:

Align menuPin menu

Below is an example of my example in Interface Builder. The blue view is the “parent view” from the original question, this view in which the image and label must be centered.

I added a green view (which I called viewCenteredInLeftSection ) as a subitem of the "parent view". Then I selected it and used the Alignment menu “Horizontal Center in Container” and “Vertical Center in Container” to create restrictions for determining its position.

I added an image of the clock as a subitem of viewCenteredInLeftSection , with restrictions determining its width and height. I selected the clock image and viewCenteredInLeftSection , then applied the restrictions using Align> Leading Edges, Align> Top Edges and Align> Bottom Edges.

I added the label as a subset of viewCenteredInLeftSection , positioning it as the standard distance in the Aqua space from the clock image. I highlighted the label and viewCenteredInLeftSection , then applied the constraints using Align> Trailing Edges.

It was a lot easier to create with Xcode 5 Interface Builder and Xcode 4.

Interface builder

+58
Feb 07 '13 at 15:32
source share

I figured out the way without adding another view:

  [aView addConstraint:[NSLayoutConstraint constraintWithItem:viewOnLeft attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationLessThanOrEqual toItem:aView attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]]; [aView addConstraint:[NSLayoutConstraint constraintWithItem:viewOnRight attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationLessThanOrEqual toItem:aView attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]]; 

You can also modify constants to create a gap between views.

  • left constraint constant: -X
  • rights limitation constant: +X

centering subviews

+28
Feb 08 '13 at 1:11
source share

It took me a little time, but I realized a pretty solid solution. I understood the same solution provided by John Sauer, but did not want to add another view to wrap them.

The answer requires three steps.

1) The width of my subset, which contains the other two, which I will call leftInfoSection , must be determined by the content. This eliminates the need for it to have left and right constraints for the supervisor (or other representation) to determine its width. This is a real key with a lot of this material, allowing you to determine the width for children.

enter image description here

2) I still had to have a leading restriction in IB in order to have a valid layout. (He should have known where to place the leftInfoSection horizontally). Connect this restriction to your code so that it can be removed. In addition to this, I had the final GTE limit on the vertical divider + 3.

3) The last key is to think about what information you should work with (in code, since IB is limited). I realized that I knew the center of the horizontal separator above my section and that the center of my leftInfoSection would be the center of this horizontal bar minus 1/4 of the width of the horizontal bar. Here is the last code for the left and right side:

 // remove the unwanted constraint to the right side of the thumbnail [self.questionBox removeConstraint:self.leftInfoViewLeadingConstraint]; // calculate the center of the leftInfoView CGFloat left = self.horizontalDividerImageView.frame.size.width/4 * -1; // constrain the center of the leftInfoView to the horizontal bar center minus a quarter of it to center things [self.questionBox addConstraint:[NSLayoutConstraint constraintWithItem:self.leftInfoView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.horizontalDividerImageView attribute:NSLayoutAttributeCenterX multiplier:1 constant:left]]; // remove the unwanted constraint to the right side of the questionBox [self.questionBox removeConstraint:self.rightInfoViewTrailingConstraint]; // calculate the center of the rightInfoView CGFloat right = left * -1; // constrain the center of the rightInfoView to the horizontal bar center plus a quarter of it to center things [self.questionBox addConstraint:[NSLayoutConstraint constraintWithItem:self.rightInfoView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.horizontalDividerImageView attribute:NSLayoutAttributeCenterX multiplier:1 constant:right]]; 

Result: Final result

In addition, IB can be very annoying how it automatically updates restrictions. When I tried to define the start and end limits for subviews as 0, it would continue to disable one or the other and create a limit for the supervisor to determine the width. The trick was to temporarily leave this unwanted restriction temporarily, but lower its priority to 999. Then I managed to create, but restrict the subview to determine the width.

+16
Feb 07 '13 at 18:41
source share

The solution to this issue is discussed in lectures at Stanford University on ios 7. It works great. Attached here is a solution. (Here sdfssfg ... thing - label1 and efsdfg .... thing - label2)

enter image description here

+14
May 02 '15 at 4:19
source share

This works very well, but requires 2 UIView spacers:

 UIView *spacer1 = [[UIView alloc] init]; spacer1.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:spacer1]; UIView *spacer2 = [[UIView alloc] init]; spacer2.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:spacer2]; NSDictionary *views = NSDictionaryOfVariableBindings(spacer1, spacer2, imageView, label); [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[spacer1(>=0)][imageView]-4-[label][spacer2(==spacer1)]|" options:0 metrics:nil views:views]; for (int i = 0; i < constraintsArray.count; i++) { [self.view addConstraint:constraintsArray[i]]; } 
+11
Nov 16 '13 at 7:38
source share

After iOS 9, another option for this is Stack Views.

+5
Dec 23 '15 at 19:31
source share

You might want to refer to this

Percentage marking

Basically, he says that he was first with an invalid field, and then corrected it with respect to his parent view.

Work with my case.

0
Aug 25 '15 at 14:50
source share

There are several ways to do this. Basically, here's how to concentrate 1..n items, assuming that all of your items are limited in size and will not grow.

  • Place 2 spacers on each side of your items. Attach the spacers to the parent edges. Attach your first and last elements to the anchors. Finally, assign 1 spacer the width of another spacer. You do not need to explicitly specify the size of the spacer, as it will be allowed.

    • spacer1 -> left = parent: left width = spacer2: width
    • spacer2 → right = parent: right
    • yourFirstItem → left = spacer1: right
    • yourLastItem → right = spacer2: left
  • If the pads are not your thing, and you and you have an odd number of items, center the middle to the center of the parent. Also, make sure that the first and last elements are not mapped to the parent edges.

    • yourMiddleItem = centerX = parent: centerX
    • otherItems-> yourMiddleItem <-otherItems
  • If the spacers are not your thing and you have an even number of items, center the edges of the two internal items to the center of the parent. Also, make sure that the first and last elements are not mapped to the parent edges.

    • leftMiddleItem -> right = parent: centerX
    • rightMiddleItem -> left = parent: centerX
    • otherItems-> leftMiddleItem rightMiddleItem <-otherItems
  • You can also center the invisible placeholder in the center and snap to it, but you still have to consider the odd / even number of elements when limiting, so I do not recommend this approach.

0
Dec 09 '17 at 2:06
source share



All Articles