5

我正在向 a 添加一个 UIViewUIScrollView并对其进行约束,使其填充水平空间,除了一些边距。我的视觉约束如下所示:

@"|-16-[theLineView]-16-|"

我已将视图设置为一个像素高,因此它将显示为一条线,并将其放置在两个文本标签之间:

@"V:[someOtherStuff]-[aTextLabel]-[theLineView]-[anotherLabel]"

但是,我发现线条的宽度只会扩大到其上方/下方最长标签的宽度。

为什么会这样?

PS我读过这个http://developer.apple.com/library/ios/#technotes/tn2154/_index.html

在此处输入图像描述

代码

以下是在 iPad sim 上展示此问题的测试项目中的完整视图控制器代码。

- (void)viewDidLoad

{ [超级 viewDidLoad];

self.scrollView = [[UIScrollView alloc] init];
self.scrollView.translatesAutoresizingMaskIntoConstraints = NO;
self.scrollView.backgroundColor = [UIColor greenColor];
[self.view addSubview:self.scrollView];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[scrollView]|"
                                                                 options:0
                                                                 metrics:0
                                                                   views:@{@"scrollView":self.scrollView}]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]|"
                                                                  options:0
                                                                  metrics:0
                                                                    views:@{@"scrollView":self.scrollView}]];

self.line1 = [[UIView alloc] init];
self.line2 = [[UIView alloc] init];
self.label1 = [[UILabel alloc] init];
self.label2 = [[UILabel alloc] init];
self.label3 = [[UILabel alloc] init];

for (UILabel *label in @[self.label1, self.label2, self.label3])
{
    label.text = @"I am a label and I am long enough that I can be multiline on an iphone but single on ipad";
}

for (UIView *view in @[self.line1, self.line2, self.label1, self.label2, self.label3])
{
    view.translatesAutoresizingMaskIntoConstraints = NO;
    view.backgroundColor = [UIColor redColor];
    [self.scrollView addSubview:view];
}

//horizontal layout - all views/labels should fill the horizontal space expect for margin
for (UIView *view in  @[self.line1, self.line2, self.label1, self.label2, self.label3])
{
    NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|-16-[view]-16-|"
                                                                   options:0
                                                                   metrics:0
                                                                     views:@{@"view":view}];
    [self.scrollView addConstraints:constraints];
}

//vertical layout - stack em up
[self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[lab1]-[line1(==1)]-[lab2]-[line2(==1)]-[lab3]-|"
                                                                  options:0
                                                                  metrics:0
                                                                    views:@{@"lab1":self.label1, @"line1":self.line1, @"lab2":self.label2, @"line2":self.line2, @"lab3":self.label3}]];

}

4

4 回答 4

7

UIScrollView 会自动缩小以适应其中的视图。您需要在某处绝对设置宽度。

推荐战术:

  1. 使用约束(前导、尾随、顶部、底部)完全固定其父视图内的滚动视图。
  2. 在 UIScrollView 中创建一个 UIView 并将您需要的所有内容放入其中。
  3. 设置约束,以便 UIView 将充当内容视图(这意味着它足够大以包含所有元素)。大量使用固有的内容大小、抗收缩性和带有约束的元素链接。生成的布局必须定义明确且唯一(这意味着如果您要移除外部的所有约束,布局仍然可以工作)。
  4. 将 UIView 的边界与它们的超级视图(这是 UIScrollView 的实际内容视图,而不是 UIScrollView!)连接起来。

如果您在 interface-builder 中执行此操作(这是可能的),则每次在该场景中触摸某些东西时都需要重新检查您的约束。触摸我的意思是“选择”不仅仅是“修改”。

于 2013-07-21T19:47:21.667 回答
2

找到了一个适用于您的用例的有效解决方案。见这里

于 2013-09-24T11:14:06.173 回答
2

扩展 Patric Sc​​henke 答案的第 4 点;因为 的内容大小scrollView是可变的,所以将内部视图固定到其边缘并不能确定视图的宽度。您的左侧销会起作用,但两者都不会。根据上一级容器计算视图的宽度是要走的路。只要将您self.scrollView的容器固定到其容器(我称之为containerView),这行代码就会完成您想要的。将此行添加到您的for循环中以获取水平约束:

// Pin view's width to match the scrollView container's width
// -32 constant offset for margins
[containerView addConstraint:
  [NSLayoutConstraint constraintWithItem:view 
                               attribute:NSLayoutAttributeWidth
                               relatedBy:NSLayoutRelationEqual
                                  toItem:containerView
                               attribute:NSLayoutAttributeWidth
                              multiplier:1.0f
                                constant:-32]];
于 2014-02-25T20:26:36.103 回答
0

我找到了一种简单的基于约束的方法来实现这一点(我还没有测试过这个解决方案的脆弱程度):

...@"H:|-16-[view]-16-|"... // (your original constraint)

[self.scrollView addConstraint:
  [NSLayoutConstraint constraintWithItem:view 
                               attribute:NSLayoutAttributeCenterX
                               relatedBy:NSLayoutRelationEqual
                                  toItem:self.scrollView
                               attribute:NSLayoutAttributeCenterX
                              multiplier:1.0f
                                constant:0.0f]];

这一直延伸view到视图的另一侧。这对于水平滚动但应该垂直滚动的内容可能并不理想。

我意识到这是一年多之后的事了,但是对于单维滚动用例来说,它比 patric.schenke 的答案更简单(很好而且更健壮)。

于 2014-10-29T20:46:48.360 回答