スクロール ビューの制約は、他のビューとは少し異なります。contentView
とそのsuperview
(the scrollView
)の間の制約は、そのではなく、scrollView
のものです。これは紛らわしいように思えるかもしれませんが、実際には非常に便利です。つまり、 を調整する必要はなく、コンテンツに合わせて が自動的に調整されます。この動作については、テクニカル ノート TN2154で説明されています。contentSize
frame
contentSize
contentSize
contentView
画面のサイズなどを定義したい場合はcontentView
、たとえば、 とメイン ビューの間に制約を追加する必要があります。確かに、それはコンテンツをスクロールビューに入れることとは正反対なので、おそらくそれはお勧めしませんが、それは可能です。
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
をメイン ビューの幅にも合わせたい場合は、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;
});