以下代码(在viewDidLoad中称为)导致屏幕全红。我希望它是一个完全绿色的屏幕。为什么是红色?我怎么能做到绿色呢?
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];
NSDictionary* viewDict = NSDictionaryOfVariableBindings(scrollView,contentView);
[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]];
最佳答案
滚动 View 的约束与其他 View 的约束稍有不同。 contentView
及其superview
(即scrollView
)之间的约束条件是scrollView
的contentSize
,而不是frame
。这可能看起来令人困惑,但实际上它非常有用,这意味着您不必调整contentSize
,而是contentSize
会自动调整以适合您的内容。此行为在Technical Note TN2154中进行了描述。
例如,如果要在屏幕上定义contentView
大小或类似内容,则必须在contentView
和主 View 之间添加约束。诚然,那是与将内容放入滚动 View 相对的,所以我可能不建议这样做,但是可以做到。
为了说明这个概念,contentView
的大小将由其内容决定,而不是由bounds
的scrollView
决定,请在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
(因此是contentSize
的scrollView
)已调整为适合带有标准边距的标签。而且因为我没有指定标签的宽度/高度,所以它将根据您放入该标签的文本进行调整。如果您希望
contentView
也调整为主 View 的宽度,则可以像这样重新定义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]];
在滚动 View 中有一个带有多行标签的known issue (bug?),如果您希望它根据文本量来调整大小,则必须花些力气,例如:
dispatch_async(dispatch_get_main_queue(), ^{
randomLabel.preferredMaxLayoutWidth = self.view.bounds.size.width;
});
关于ios - 使用UIScrollview的iOS自动布局: Why does content view of scroll view not fill the scroll view?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16843633/