【问题标题】:Simplest way to evenly distribute UIButtons horizontally across width of view controller?在视图控制器的宽度上水平均匀分布 UIButton 的最简单方法?
【发布时间】:2013-09-13 10:14:32
【问题描述】:

我查看了很多答案,它们看起来都非常复杂!最近我在看this answer,尽管我不希望将按钮放在视图中。

我有 6 个尺寸相同的 UIButton。我想在我的根视图控制器的整个宽度和底部均匀地水平放置它们。

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

以编程方式实现这一目标的最简单方法是什么?

【问题讨论】:

  • 您的解决方案不是最简单的方法,如果您添加或删除按钮,您必须重新计算乘数。请参阅我的答案以了解正确的方法。我的解决方案还满足您不想将按钮嵌套在视图中的其他要求。

标签: iphone ios objective-c uibutton autolayout


【解决方案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]];

结果:

【讨论】:

  • 感谢 bandejapaisa - 这更优雅!
  • 不知何故这对我不起作用,所以我在 Swift 中创建了这个帮助程序类:DistributeViewsEvenly-Swift,它使用了不可见的间隔符,正如 Apple 在 this documentation 中推荐的那样
  • @chrisben 我认为您的解决方案值得单独回答,而不仅仅是评论。
  • 我们如何设置按钮的'Y'位置,例如button1.frame.origin.y = 50
  • 我连续有 5 个按钮,尺寸分别为:75 x 50 完全填充到 4.7 英寸屏幕。当我试图限制它也适合 4 英寸但比例刚刚打破。如何在为小屏幕缩放按钮的同时遵守比例?
【解决方案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 是您想要的任何 y 坐标,高度和间隙也是如此,即按钮之间的空间。宽度只是根据屏幕宽度和每个按钮之间所需的间隙空间计算每个按钮的宽度。

      【讨论】:

        【解决方案5】:

        您可以将标签/按钮/视图作为数组发送到此方法并排列按钮框架。

        -(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】:

          在这个问题中讨论了许多不错的自动布局解决方案:

          Evenly space multiple views within a container view

          基本上它可以是很多手动的约束定义代码,可以方便地包装在类别扩展中以进行封装/重用。

          【讨论】:

            【解决方案7】:

            我刚刚使用 Cartography 在 Swift 中完成了这个。

            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 和 swift 非常有帮助。无论如何,下面是我对上述问题的快速解决方案。

              分别固定最左边的按钮和最右边的按钮。 在每个按钮之间创建“虚拟”标签。将所有“虚拟”标签设置为等宽。对于每个“虚拟”标签,添加约束(0 到左侧最近的邻居,0 到右侧最近的邻居)。即使您从纵向更改为横向,这些按钮也会在整个过程中等距分布。

              【讨论】:

                猜你喜欢
                • 2014-05-29
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-05-05
                • 2019-09-26
                相关资源
                最近更新 更多