滚动视图的约束与其他视图略有不同。
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]];
在滚动视图中,多行标签存在一个已知问题(错误?),如果你想让它根据文本量自动调整大小,你需要进行一些巧妙的处理,例如:
dispatch_async(dispatch_get_main_queue(), ^{
randomLabel.preferredMaxLayoutWidth = self.view.bounds.size.width;
});