問題描述
以下代碼(在 viewDidLoad 中調用)會導致屏幕全紅.我希望它是一個完全綠色的屏幕.為什么是紅色的?我怎樣才能讓它全部變成綠色?
The following code (called in viewDidLoad) results in a fully red screen. I would expect it to be a fully green screen. Why is it red? And how can I make it all green?
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]];
推薦答案
滾動視圖的約束與其他視圖的約束略有不同.contentView
和它的 superview
(scrollView
)之間的約束是對 scrollView
的 contentSize
,而不是它的 frame
.這可能看起來令人困惑,但實際上非常有用,這意味著您不必調整 contentSize
,而是 contentSize
會自動調整以適應您的內容.技術說明 TN2154 中描述了這種行為.
Constraints with scroll views work slightly differently than it does with other views. The constraints between of contentView
and its superview
(the scrollView
) are to the scrollView
's contentSize
, not to its frame
. This might seem confusing, but it is actually quite useful, meaning that you never have to adjust the contentSize
, but rather the contentSize
will automatically adjust to fit your content. This behavior is described in Technical Note TN2154.
如果你想在屏幕上定義 contentView
大小或類似的東西,你必須在 contentView
和主視圖之間添加一個約束,例如例子.誠然,這與將內容放入滾動視圖是對立的,所以我可能不建議這樣做,但可以這樣做.
If you want to define the contentView
size to the screen or something like that, you'd have to add a constraint between the contentView
and the main view, for example. That's, admittedly, antithetical to putting content into the scrollview, so I probably wouldn't advise that, but it can be done.
為了說明這個概念,contentView
的大小將由其內容驅動,而不是由 scrollView
的 bounds
驅動,添加contentView
的標簽:
To illustrate this concept, that the size of contentView
will be driven by its content, not by the bounds
of the scrollView
, add a label to your 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
)已調整為適合標簽標準邊距.而且因為我沒有指定標簽的寬度/高度,它會根據您放入該標簽的文本進行調整.
Now you'll see that the contentView
(and, therefore, the contentSize
of the scrollView
) are adjusted to fit the label with standard margins. And because I didn't specify the width/height of the label, that will adjust based upon the text you put into that label.
如果您希望 contentView
也調整到主視圖的寬度,您可以像這樣重新定義您的 viewDict
,然后添加這些額外的約束(在除了以上所有其他內容):
If you want the contentView
to also adjust to the width of the main view, you could do redefine your viewDict
like so, and then add these additional constraints (in addition to all the others, above):
UIView *mainView = self.view;
NSDictionary* viewDict = NSDictionaryOfVariableBindings(scrollView, contentView, randomLabel, mainView);
[mainView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[contentView(==mainView)]" options:0 metrics:0 views:viewDict]];
<小時>
有一個已知問題(錯誤?) 在滾動視圖中帶有多行標簽,如果你希望它根據文本量調整大小,你必須做一些花招,例如:
There is a known issue (bug?) with multiline labels in scrollviews, that if you want it to resize according to the amount of text, you have to do some sleight of hand, such as:
dispatch_async(dispatch_get_main_queue(), ^{
randomLabel.preferredMaxLayoutWidth = self.view.bounds.size.width;
});
這篇關于iOS Autolayout with UIScrollview:為什么滾動視圖的內容視圖不填充滾動視圖?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!