滚动视图的约束与其他视图的约束不同。 contentView
及其superview
(scrollView
)之间的限制条件为scrollView
的contentSize
,而不是其frame
。这看起来可能会让人困惑,但实际上它非常有用,这意味着您不必调整contentSize
,而是contentSize
会自动调整以适合您的内容。此行为在Technical Note TN2154中描述。
例如,如果要将contentView
大小定义为屏幕或类似内容,则必须在contentView
与主视图之间添加约束。诚然,与将内容放入滚动视图相反,所以我可能不会建议这样做,但它可以完成。
为了说明这个概念,是的contentView
的大小由它的内容来驱动,而不是由scrollView
的bounds
,添加标签到您的contentView
:
UIScrollView* scrollView = [UIScrollView new];
scrollView.translatesAutoresizingMaskIntoConstraints = NO;
scrollView.backgroundColor = [UIColor redColor];
[self.view addSubview:scrollView];
UIView* contentView = [UIView new];
contentView.translatesAutoresizingMaskIntoConstraints = NO;
contentView.backgroundColor = [UIColor greenColor];
[scrollView addSubview:contentView];
UILabel *randomLabel = [[UILabel alloc] init];
randomLabel.text = @"this is a test";
randomLabel.translatesAutoresizingMaskIntoConstraints = NO;
randomLabel.backgroundColor = [UIColor clearColor];
[contentView addSubview:randomLabel];
NSDictionary* viewDict = NSDictionaryOfVariableBindings(scrollView, contentView, randomLabel);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|" options:0 metrics:0 views:viewDict]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]|" options:0 metrics:0 views:viewDict]];
[scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[contentView]|" options:0 metrics:0 views:viewDict]];
[scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[contentView]|" options:0 metrics:0 views:viewDict]];
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[randomLabel]-|" options:0 metrics:0 views:viewDict]];
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[randomLabel]-|" options:0 metrics:0 views:viewDict]];
现在,您将请参阅contentView
(并因此调整scrollView
的contentSize
)以适应具有标准边距的标签。因为我没有指定标签的宽度/高度,所以会根据您放入该标签的文字进行调整。
如果你想contentView
也调整到主视图的宽度,你可以做重新定义viewDict
像这样,然后添加这些额外的限制(除了所有其它的,上面):
UIView *mainView = self.view;
NSDictionary* viewDict = NSDictionaryOfVariableBindings(scrollView, contentView, randomLabel, mainView);
[mainView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[contentView(==mainView)]" options:0 metrics:0 views:viewDict]];
有一个known issue (bug?)在scrollviews多标签,如果你想让它根据文字的数量调整大小,你所要做的手的一些手法,如:
dispatch_async(dispatch_get_main_queue(), ^{
randomLabel.preferredMaxLayoutWidth = self.view.bounds.size.width;
});
来源
2013-05-30 19:03:37
Rob
我似乎无法获取标签,以垂直扩展,如果文本太长,以适应一条线。我已将行数设置为0,并将lineBreakMode设置为NSLineBreakByWordWrapping。我错过了什么吗? – rdelmar
此外,我在答案中添加了最后一行,以将contentView的宽度固定为屏幕的宽度(否则contentView的宽度足够宽以容纳长文本)。如果我用高度限制明确设置标签的高度,那么它就可以工作。 – rdelmar
是的,马特发现了[一些解决方法](http://stackoverflow.com/questions/13149733/ios-autolayout-issue-with-uilabels-in-a-resizing-parent-view)这个问题/多行标签的缺陷。我已将其中一个添加到我的答案的底部。彻底不满意的解决方案。看起来像你必须在硬编码值或这个kludgy解决方法之间进行选择。 – Rob