Простейший способ равномерного распределения UIButtons по горизонтали по ширине контроллера вида?
Я просмотрел множество ответов, и все они кажутся очень сложными! Совсем недавно я смотрел на этот ответ, хотя я бы предпочел не нажимать свои кнопки внутри просмотров.
У меня есть 6 UIButton, которые имеют одинаковые размеры. Я хочу разместить их равномерно горизонтально по всей ширине и внизу моего контроллера корневого представления.
| |
| |
| [b1] [b2] [b3] [b4] [b5] [b6] |
________________________________________
Каков самый простой способ достичь этого программно?
Ответы
Ответ 1
Я думаю, что это проще, чем ссылка на принятый ответ. Итак, сначала создайте несколько кнопок:
UIButton *button1 = [UIButton buttonWithType:UIButtonTypeSystem];
button1.translatesAutoresizingMaskIntoConstraints = NO;
[button1 setTitle:@"Btn1" forState:UIControlStateNormal];
... сделайте это 6 раз для 6 кнопок, однако вам понравится, затем добавьте их в представление:
[self.view addSubview:button1];
[self.view addSubview:button2];
[self.view addSubview:button3];
[self.view addSubview:button4];
[self.view addSubview:button5];
[self.view addSubview:button6];
Устраните одну кнопку в нижней части вашего представления:
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:button1 attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1 constant:0]];
Затем скажите всем кнопкам равную ширину и равномерно распределите по ширине:
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]];
Результат:
![enter image description here]()
Ответ 2
UIStackView был представлен в iOS9.
https://developer.apple.com/documentation/uikit/uistackview
Ответ 3
Я знаю, что этот вопрос немного устарел, но я программировал в iOS уже несколько лет и не люблю использовать автозапуск. Поэтому я написал вспомогательный метод для равномерного пространства UIButtons по горизонтали и центрирования по вертикали внутри UIView. Это отлично работает для строк меню.
- (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;
}
}
Просто скопируйте и вставьте этот метод в любой контроллер представления. Затем, чтобы получить к нему доступ, я сначала создал все нужные мне кнопки, а затем вызвал метод со всеми кнопками в массиве вместе с UIView, в котором я хотел.
[self evenlySpaceTheseButtonsInThisView:@[menuButton, hierarchyMenuButton, downButton, upButton] :menuView];
Преимущество этого метода заключается в том, что вам не нужна автоматическая отладка и она очень проста в реализации. Недостатком является то, что если ваше приложение работает в условиях ландшафта и портрета, вам нужно будет снова вызвать этот метод после поворота представления.
Ответ 4
Обычно я делаю что-то вроде:
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)];
}
Вы можете установить numButtons на любое количество кнопок, которые вы хотите в строке, и если у вас есть набор кнопок, вы можете установить его в length
этого массива.
Y - это то, что вы хотите, и то же самое относится к высоте и разрыву, который представляет собой пробел между кнопками. Ширина - это просто расчет того, насколько широка каждая кнопка будет основываться на ширине экрана и пространстве пробелов, которое вы хотите между каждой кнопкой.
Ответ 5
Вы можете отправить Label/button/view as array этим методам и упорядочить кадры кнопок.
-(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);
}
}
}
Вызвать этот метод следующим образом:
[self arrangeViewsXposition:@[btnSave,btnCancel] y:5 width:80 height:30 mainViewWdith:footerView];
Ответ 6
В этом вопросе обсуждается ряд достойных решений для автоматического макета:
Равномерное пространство нескольких видов в представлении контейнера
В принципе, это может быть много ручного кода определения ограничений, который удобно переносить в расширение категории для инкапсуляции/повторного использования.
Ответ 7
Я только что приготовил это в Swift, используя Cartography.
func disributeEvenlyAcrossWithCartography(views: [UIView], enclosingBox: UIView, spacer: CGFloat = 10.0) {
var priorView = UIView() // never null
for (index, view) in views.enumerate() {
constrain(view, priorView, enclosingBox) { view, prior, enclosingBox in
view.height == enclosingBox.height
view.centerY == enclosingBox.centerY
if index == 0 {
view.width == enclosingBox.width / CGFloat(views.count) - spacer
view.left == enclosingBox.left
} else {
view.left == prior.right + (spacer + spacer / CGFloat(views.count - 1))
view.width == prior.width
}
}
priorView = view
}
}
Результат с 5 видами и небольшим спейсером:
![введите описание изображения здесь]()
Ответ 8
Это мой первый пост в Stackoverflow. Этот сайт очень помог мне ускорить процесс Xcode и быстро. Во всяком случае, ниже мое быстро и грязно исправить этот вопрос.
Нажмите левую самую кнопку и самую правую кнопку, соответственно.
Создайте метки "dummy" между каждой из кнопок. Установите все метки "dummy" как равные ширины. Для каждой метки "dummy" добавьте ограничения (от 0 до ближайшего соседа слева и 0 до ближайшего соседа справа). Затем кнопки будут равномерно распределены по всему диапазону, даже если вы перейдете от портретной ориентации к альбомной ориентации.