Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS: How to create a row of controls of same percentage width

Tags:

ios

it is possible to make in interface builder or with code a row of, for example, three buttons, each with a auto width of 33%, filling entire view horizontal space?

I'm interested in both autolayout / traditional ways.

like image 210
ʞᴉɯ Avatar asked Dec 20 '22 03:12

ʞᴉɯ


1 Answers

If using auto layout, you can define the constraints, such that (a) the three subviews are the same width; (b) the first one has a leading edge to the superview; and (c) that the last one has has a training edge to the superview. In visual format language, that means that the layout is

@"H:|[view1][view2(==view1)][view3(==view1)]|"

If doing in in non-autolayout, you just define your frame for the three views such that their widths are precisely 1/3rd the width of the superview and their respective x coordinates are offset accordingly.

So, the code might look like:

UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button1 setTitle:@"1" forState:UIControlStateNormal];
button1.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:button1];

UIButton *button2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button2 setTitle:@"2" forState:UIControlStateNormal];
button2.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:button2];

UIButton *button3 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button3 setTitle:@"3" forState:UIControlStateNormal];
button3.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:button3];

NSDictionary *views = NSDictionaryOfVariableBindings(button1, button2, button3);

[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[button1][button2(==button1)][button3(==button1)]|" options:0 metrics:0 views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[button1]" options:0 metrics:0 views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[button2]" options:0 metrics:0 views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[button3]" options:0 metrics:0 views:views]];

In Interface Builder (IB), you can add the three buttons where the first is locked onto the left edge, the second is locked onto the first button, and the third is locked onto the second button:

layout buttons

You can then select all three buttons and make their width the same:

constant widths

You can then select the third button and link its trailing edge to the superview:

add trailing constraint

And you manually adjust the constant for that last constraint to be zero:

0 trailing edge

And when you do this, all three will be the same size, spanning the view. You can modify the constraints between the buttons if you want to get rid of those gaps, too. I must confess, though, that IB in Xcode 4.6.3 is a little fussy, because it keeps adding constraints that it thinks to make it unambiguous, screwing them up in the process, so some fussy tweaking is sometimes needed. Doing it in code is unambiguous. And I don't think I'm violating the NDA to say that Xcode 5 is more graceful on this sort of stuff.

--

By the way, in iOS 9, this UI may be better rendered using a "stack view". In Xcode 7, select the group of views to be distributed horizontally and then click on the stacked view button, enter image description here. Then specify the desired distribution for the stack view ("equal centering" or "equal spacing" both work well) and define the constraints to size the stack view properly (e.g. top/leading/trailing constraints).

like image 102
Rob Avatar answered Dec 24 '22 11:12

Rob