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.
UIStackView was introduced in iOS9.
https://developer.apple.com/documentation/uikit/uistackview
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.
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:
You can send the Label/button/view's as array to this methods and arrange the button frames.
-(void)arrangeViewsXposition:(NSArray*)anyView y:(CGFloat)y width:(CGFloat)width height:(CGFloat)height mainViewWdith:(UIView*)mainview {
int count = (int)anyView.count;
CGFloat widthTemp = mainview.bounds.size.width, temp1 = widthTemp-(width*count),space = temp1/(count+1);
for (int i = 0; i<count; i++) {
UIView *btnTemp = (UIView*)[anyView objectAtIndex:i];
if (btnTemp) {
btnTemp.frame = CGRectMake(space+((space+width)*i), y, width, height);
}
}
}
Call this method like this:
[self arrangeViewsXposition:@[btnSave,btnCancel] y:5 width:80 height:30 mainViewWdith:footerView];
There are a number of decent auto-layout solutions discussed in this question:
Evenly space multiple views within a container view
Basically it can be a lot of manual constraint-definition code, which can be conveniently wrapped in a category extension for encapsulation/reuse.
This is my first post on Stackoverflow. This site has been very helpful in getting me up to speed on Xcode and swift. Anyway, below is my quick-and-dirty fix to the above question.
Pin the left most button and the right most button, respectively. Create "dummy" labels between each of the buttons. Set all of the "dummy" labels as equal widths. For each of the "dummy" label, add constraints (0 to the nearest neighbor on the left, and 0 to the nearest neighbor on the right). The buttons will then be equally spaced throughout, even when you change from portrait to landscape orientation.