2013-07-21 61 views
5

我将一个UIView添加到UIScrollView并限制它,使其填充水平空间,除了一些利润率。我的视觉约束是这样的:UIView不遵守自动布局约束UIScrollView

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

我曾认为一个像素高,所以它会显示为一条线,并将其放置两个文本标签之间:

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

然而,我发现该线的宽度只扩展到最上面/最下面的标签的宽度。

这是为什么?

P.S我已阅读本http://developer.apple.com/library/ios/#technotes/tn2154/_index.html

enter image description here

代码

这里是由显示在iPad上的SIM这个问题一个测试项目视图控制器代码的全部。

- (void)viewDidLoad 

{ [super 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}]]; 

}

+0

你的1px UIView对它有没有其他约束? – Yazid

+0

[view]与[theLineView]是否一样?在选项参数中是否有任何对齐选项设置? – rdelmar

+0

选项参数中没有其他限制或任何内容。我会看看我是否可以在测试项目中复制。是的,这些观点是相同的,纠正了片段。 –

回答

6

UIScrollView的自动收缩以适应它里面的景色。你需要在某个地方设置宽度。

推荐策略:

  1. 完全fixiate滚动视图其父视图内使用约束(前置,顶部,底部)。
  2. 在UIScrollView里面创建一个UIView,并把你需要的所有东西放在里面。
  3. 设置约束,以便UIView将充当内容视图(这意味着它足够大以包含所有元素)。使用固有内容大小,缩小阻力和链接的元素与约束很多。由此产生的布局必须是明确的和独特的(这意味着如果你要去除所有的限制,布局仍然可以工作)。
  4. 连接UIView的边界与他们的超级视图(这是UIScrollView的实际内容视图,而不是UIScrollView!)。

如果你在interface-builder中做到了这一点(这是可能的),那么每次你触摸那个场景中的东西时都需要重新检查你的约束。我的意思是“选择”不仅仅是“修改”。

+0

没有为我工作,如何我设置UIView来填充滚动视图的整个宽度? – AndiDog

+0

正如我所说:contentView ALWAYS填充完整的scrollView,因为scrollView缩小了。你必须在里面设置宽度。在你的例子中,将格式从“| -16- [view] -16- |”到“| -16- [查看(288)] - 16- |”应该给你一个好的结果。 –

+3

这工作。在我看来,数字4是更好的方法,因为它很简单并且避免了任何幻数(这意味着它支持旋转等)。 –

2

找到了一个适用于您的用例的工作解决方案。见here

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]]; 
0

我发现了一个简单的基于约束的方式来做到这一点(我没有测试过这种解决方案的脆性程度):

[email protected]"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的答案更简单(它更好,更稳健)。