滚动视图的约束与其他视图的约束略有不同。 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?),如果你希望它根据文本的数量调整大小,你必须做一些花招,例如:
dispatch_async(dispatch_get_main_queue(), ^{
randomLabel.preferredMaxLayoutWidth = self.view.bounds.size.width;
});