Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simplest way to evenly distribute UIButtons horizontally across width of view controller?

I've looked through many answers and they all seem very complex! Most recently I was looking at this answer although I'd prefer not to have to put my buttons inside views.

I have 6 UIButtons that are all the same dimensions. I want to space them evenly horizontally across the full width and at the bottom of my root view controller.

|                                      |
|                                      |
|  [b1]  [b2]  [b3]  [b4]  [b5]  [b6]  |
________________________________________

What is the simplest way to achieve this programmatically?

like image 276
fxfuture Avatar asked Sep 09 '13 20:09

fxfuture


4 Answers

I think this is simpler than the link on the accepted answer. Ok, firstly lets create some buttons:

UIButton *button1 = [UIButton buttonWithType:UIButtonTypeSystem];
button1.translatesAutoresizingMaskIntoConstraints = NO;
[button1 setTitle:@"Btn1" forState:UIControlStateNormal];

... do that 6 times for 6 buttons, however you like then add them to the view:

[self.view addSubview:button1];
[self.view addSubview:button2];
[self.view addSubview:button3];
[self.view addSubview:button4];
[self.view addSubview:button5];
[self.view addSubview:button6];

Fix one button to the bottom of your view:

[self.view addConstraint:[NSLayoutConstraint constraintWithItem:button1 attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1 constant:0]];

Then tell all the buttons to be equal width and spread out equally across the width:

NSDictionary *views = NSDictionaryOfVariableBindings(button1, button2, button3, button4, button5, button6);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[button1][button2(==button1)][button3(==button1)][button4(==button1)][button5(==button1)][button6(==button1)]|" options:NSLayoutFormatAlignAllBottom metrics:nil views:views]];

Result:

enter image description here

like image 101
bandejapaisa Avatar answered Oct 19 '22 21:10

bandejapaisa


UIStackView was introduced in iOS9.

https://developer.apple.com/documentation/uikit/uistackview

like image 39
Albin Stigo Avatar answered Oct 19 '22 20:10

Albin Stigo


I know this question is a bit old, but I've been programming in iOS for a few years now and dislike using autolayout. So I wrote a helper method to evenly space UIButtons horizontally and center them vertically within a UIView. This works great for menu bars.

- (void) evenlySpaceTheseButtonsInThisView : (NSArray *) buttonArray : (UIView *) thisView {
    int widthOfAllButtons = 0;
    for (int i = 0; i < buttonArray.count; i++) {
        UIButton *thisButton = [buttonArray objectAtIndex:i];
        [thisButton setCenter:CGPointMake(0, thisView.frame.size.height / 2.0)];
        widthOfAllButtons = widthOfAllButtons + thisButton.frame.size.width;
    }

    int spaceBetweenButtons = (thisView.frame.size.width - widthOfAllButtons) / (buttonArray.count + 1);

    UIButton *lastButton = nil;
    for (int i = 0; i < buttonArray.count; i++) {
        UIButton *thisButton = [buttonArray objectAtIndex:i];
        if (lastButton == nil) {
            [thisButton setFrame:CGRectMake(spaceBetweenButtons, thisButton.frame.origin.y, thisButton.frame.size.width, thisButton.frame.size.height)];
        } else {
            [thisButton setFrame:CGRectMake(spaceBetweenButtons + lastButton.frame.origin.x + lastButton.frame.size.width, thisButton.frame.origin.y, thisButton.frame.size.width, thisButton.frame.size.height)];
        }

        lastButton = thisButton;
    }
}

Just copy and paste this method into any view controller. Then to access it, I first created all the buttons I wanted, then called the method with all of the buttons in an array, along with the UIView I wanted it in.

[self evenlySpaceTheseButtonsInThisView:@[menuButton, hierarchyMenuButton, downButton, upButton] :menuView];

The advantage of this method is that you don't need autolayout and it's super easy to implement. The disadvantage is that if your app works in landscape and portrait, you will need to make sure to call this method again after the view has been rotated.

like image 3
Kjell Avatar answered Oct 19 '22 20:10

Kjell


I usually do something like:

int numButtons = 6;
float gap = 10.0f;
float y = 50.0f;
float width = (self.view.frame.size.width - gap * (numButtons + 1)) / numButtons;
float height = 60.0f;
for (int n=0;n<numButtons;n++) {
    float x = gap * (n+1) + width * n;
    UIButton *button = [self.buttons objectAtIndex:n]; //Or get button some other way/make button.
    [button setFrame:CGRectMake(x,y,width,height)];
}

You can set numButtons to however many buttons you want in the row, and if you have an array of buttons, you can set it to the length of that array.

The y is just whatever y coordinate you want and the same goes for the height and gap, which is the space between buttons. The width is just a calculation of how wide each button will be based on the screen width and the gap space you want between each button.

like image 1
Jsdodgers Avatar answered Oct 19 '22 19:10

Jsdodgers