iOS自动布局:相等的空间以适应超级视图宽度[重复]

Posted

技术标签:

【中文标题】iOS自动布局:相等的空间以适应超级视图宽度[重复]【英文标题】:iOS Auto Layout: Equal Spaces to Fit Superviews Width [duplicate] 【发布时间】:2012-12-03 09:25:19 【问题描述】:

可能重复:Autolayout Even Spacing

我正在尝试创建一个带有按钮的可滚动条(类似于UISegmentedControl)。超级视图是UIScrollView。一旦按钮不适合滚动视图,滚动视图应该是可滚动的。到目前为止,几乎一切正常:

有很多按钮(向右滚动):

按钮不多:

现在,我的目标是,如果所有按钮都有空间,它们应该均匀分布在整个 320 像素视图中。 如何为按钮之间的空间定义约束?

现在,我正在使用以下约束(self 是 UIScrollView):

UIView *firstButton = self.buttons[0];

[self.buttonConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"|-(5)-[firstButton]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(firstButton)]];

UIView *lastButton = [self.buttons lastObject];

[self.buttonConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"[lastButton]-(5)-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(lastButton)]];

UIView *previousView = nil;

for (UIView *view in self.buttons) 
    if (previousView) 
        [self.buttonConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"[previousView]-(5)-[view]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(previousView, view)]];
    
    previousView = view;

如果我将超级视图的类型从UIScrollView 更改为UIView,我会得到以下结果,但仍然不是我想要的,但至少它会查找将其与右边缘(有道理,滚动视图不会发生这种情况,因为内容大小是自动设置的):

有什么想法吗?

【问题讨论】:

当你说“在整个 320px 视图中均匀分布”时,你的意思是每个按钮之间的空间都将具有相同的宽度,对吗?在您的示例代码中,您应用约束将每个视图水平间隔 5 点。 5 点是猜测,还是你确定你的 4 个按钮的宽度加上 5 个 5 点间距的实例加起来等于超级视图的宽度? 【参考方案1】:
- (void) viewWillLayoutSubviews 
    // UIButton *button1, *button2, *button3, *button 4 ;
    // NSMutableArray *constraintsForButtons ;

    float unusedHorizontalSpace = self.view.bounds.size.width - button1.intrinsicContentSize.width - button2.intrinsicContentSize.width - button3.intrinsicContentSize.width - button4.intrinsicContentSize.width ;
    NSNumber* spaceBetweenEachButton=  [NSNumber numberWithFloat: unusedHorizontalSpace / 5 ] ;

    [self.view removeConstraints:constraintsForButtons] ;
    [constraintsForButtons removeAllObjects] ;
    [constraintsForButtons addObjectsFromArray: [NSLayoutConstraint constraintsWithVisualFormat: @"H:|-(space)-[button1]-(space)-[button2]-(space)-[button3]-(space)-[button4]-(space)-|"
                                                                                        options: NSLayoutFormatAlignAllCenterY
                                                                                        metrics: @@"space":spaceBetweenEachButton
                                                                                          views: NSDictionaryOfVariableBindings(button1,button2,button3,button4) ] ] ;
    [constraintsForButtons addObjectsFromArray: [NSLayoutConstraint constraintsWithVisualFormat: @"V:|[button1]"
                                                                                        options: 0
                                                                                        metrics: nil
                                                                                          views: NSDictionaryOfVariableBindings(button1) ] ] ;
    [self.view addConstraints:constraintsForButtons] ;

这不像你的那么漂亮,它假设有 4 个按钮,但它们的间距相等。也就是说,按钮之间的空白空间都具有相同的宽度。这并不意味着button1和button2的NSLayoutAttributeLeading之间的距离与button2和button3之间的距离一样。

【讨论】:

现在这是答案。 好吧,它并不像我希望的那样完全依赖于没有您自己的计算的自动布局,但它是一个可行的解决方案,在这种情况下可以帮助我(另外,因为我不知道你可以像这样使用metrics参数)。谢谢。 是的,最好说“(button1 的 NSLayoutAttributeTrailing - button2 的 NSLayoutAttributeLeading)==(button2 的 NSLayoutAttributeTrailing - button3 的 NSLayoutAttributeLeading)”等,但我不知道有什么办法。您可以初始化 UIView,将它们留空,然后在 @"[emptyView1][button1][emptyView2(==emptyView1)][button2]…" 之类的约束中使用它们,但知识渊博的人可能会告诉你这是在浪费资源。 这个技巧是如果间距最终像 23.333333 一样奇怪。然后它会破裂。解决方案是先对其进行 fmod 以获得任何潜在的余数,然后缩小间距并将余数添加到最后一个(不应该引起注意)。 CGFloat remainder = fmod(totalSpace, 3); CGFloat spacing = floor(totalSpace /3);

以上是关于iOS自动布局:相等的空间以适应超级视图宽度[重复]的主要内容,如果未能解决你的问题,请参考以下文章

iOS自动布局两个UIView具有相等的宽度

如何在ios swift中以编程方式创建自动布局等宽度约束?

自动更改 textSize 以适应布局宽度 [重复]

iOS自动布局:给顶部空间等于superview高度的1/5

iOS:自适应集合视图单元格宽度

iOS 如何设置约束以适应设备屏幕?