4

I need to layout a series of buttons horizontally across the screen so that they're equally spaced across the screen, not equally spaced between themselves. An example is having 3 buttons there they are evenly spaced so that the first button is centered at 25% of the screen width and others are 50%, 75% of the screen width.

This is relatively straightforward manually placing them in x,y coordinates but I'm trying to avoid mixing approaches.

The prevailing recommendation is to use spacers (UIView) between the buttons and put a constraint to make the spacers equal. This does not work if the buttons being spaced are of potentially different sizes. Say there are 3 buttons labeled, "A", "B", "ReallyLong". I still want them centered, with "B" in the middle of the screen. Equal spacers leaves equal spacing between them but not evenly distributed buttons. ReallyLong takes up too much room and B is not centered

enter image description here

David
  • 2,770
  • 5
  • 35
  • 43

3 Answers3

7

You can create a constraint to align the centerX of a button to its container. Then, edit that constraint so that the centerX of the button is equal to the container's trailing attribute, with a multiplier of 0.25, 0.5, or 0.75 (and a 0 constant). To do this most naturally, you may need to tell Xcode to swap the first and second items, so that Button.CenterX equals Superview.Trailing (with multiplier) rather than the other way around.

Ken Thomases
  • 88,520
  • 7
  • 116
  • 154
  • 1
    This should have been the answer as it doesn't need spacers – Naveen Ramanathan Mar 10 '16 at 18:33
  • Exactly as @hackphone says, it's much nicer without spacers, here is a really nice quick answers how to do it without spacers: http://stackoverflow.com/a/25898949/1953914 – hashier Aug 03 '16 at 14:34
5

Apple has explained it really well.

Creating Equal Spacing Between Views

To lay out several views that are proportionally spaced based on the orientation of a device, create spacer views between the visible views. Set the constraints of these spacer views correctly to ensure that the visible views are able to stay spaced apart based on the orientation of the device.

The following example uses the steps in the above task to show how to position two views proportionally spaced. The spacer views are annotated for the example, but are normally left empty with no background. First, create the two views and place them in the storyboard.

enter image description here

Add the three spacer views—one to the left of the leftmost view, one between the two views, and one to the right of the rightmost view. The spacer views don’t have to be the same size at this time because their size will be set through constraints.

enter image description here

Create the following constraints for the spacer views:

  • Constrain the width of spacer view 2 and spacer view 3 to be equal to the width of spacer view 1.

  • Constrain the width of spacer view 1 to be greater than or equal to
    the minimum desired width.

  • Create a Leading Space to Container constraint from spacer view 1 to the container.

  • Create a Horizontal Spacing constraint from spacer view 1 to view 1. Set this constraint to be a less-than-or-equal-to constraint with a
    priority of 1000.

  • Create Horizontal Spacing constraints from spacer view 2 to view 1
    and view 2. Set these constraints to be a less-than-or-equal-to
    constraint with a priority of 999.

  • Create a Horizontal Spacing constraint from spacer view 3 to view 2. Set this constraint to be a less-than-or-equal-to constraint with a
    priority of 1000.

  • Create a Trailing Space to Container constraint from spacer view 3 to the container.

These constraints create two visible views and three invisible views (spacer views). These spacer views automatically resize as the orientation of the device changes, keeping the visible views proportionally spaced, as shown in the following two figures:

enter image description here

enter image description here

Omer Waqas Khan
  • 2,423
  • 4
  • 33
  • 62
  • This answer give me the way to solve my problem: 4 buttons equal width and evenly spaced. Solved by creating the mentioned spacer widths with width equality constraint between all of them, no explicit width constraint for spacer but the **key has been a center y alignment constraint for the middle spacer**. – BuguiBu Nov 03 '17 at 16:02
4

I think I solved it. I have earlier been able to get even spaces BETWEEN buttons by inserting spacers between each button and setting the spacer widths to be equal. And addition is to also specify that the button widths are equal. This seems to be working well. All the text is centered in the appropriate place.

For 3 buttons, here's the one visual constraint that seems to do it.

Constraint = "H:|[spacer0(>=0)][button0][spacer1(==spacer0)][button1(==button0)][spacer2(==spacer0)][button2(==button0)][spacer3(==spacer0)]|"

With the above text it looks like this, which is what I was looking for. The middle button is centered, the right button is centered on the right third of the screen:

enter image description here

David
  • 2,770
  • 5
  • 35
  • 43