iOS自动布局:等间距适应父视图宽度

12

可能是重复内容:
Autolayout Even Spacing

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

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

Scrolled View

没有那么多按钮:

View is not scrolling

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

现在,我正在使用以下约束条件(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,则会得到以下结果,仍然不是我想要的,但至少它在查找最后一个按钮的约束时会将其绑定到右侧边缘(这是有道理的,因为对于UIScrollView,内容大小是自动设置的):

UIView as the superview

有什么想法吗?


当你说“平均分布在整个320像素视图上”时,你的意思是每个按钮之间的空间都会有相同的宽度,对吗?在你的示例代码中,你应用了水平方向上每个视图之间5个点的约束。这个5个点是猜测出来的吗,还是你确定你的4个按钮的宽度加上5个5点间距的实例等于父视图的宽度? - John Sauer
1个回答

20
- (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之间的距离相同。

肖像 风景


6
那才是一个答案。 - jrturton
好的,它并不完全依赖于自动布局而没有你自己的计算,但这是一个可行的解决方案,在这种情况下帮助了我(另外,我不知道你可以像那样使用度量参数)。谢谢。 - denbec
是的,说“(button1的NSLayoutAttributeTrailing - button2的NSLayoutAttributeLeading)==(button2的NSLayoutAttributeTrailing - button3的NSLayoutAttributeLeading)”会更好,但我不知道有什么方法可以这样做。您可以初始化UIView,将它们保留为空,并在约束中使用它们,例如@"[emptyView1][button1][emptyView2(==emptyView1)][button2]…",但更有经验的人可能会告诉您这是浪费资源。 - John Sauer
1
这个问题的关键在于如果间距出现奇怪的情况,比如23.333333。那么它就会出错。解决方法是先使用fmod获取任何潜在的余数,然后向下舍入您的间距并将余数添加到最后一个间距上(不应该被注意到)。CGFloat remainder = fmod(totalSpace, 3); CGFloat spacing = floor(totalSpace /3); - Bob Spryn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接