Ограничения с просмотром прокрутки работают несколько иначе, чем с другими видами. Ограничения между contentView
и его superview
(scrollView
) относятся к scrollView
contentSize
, а не к его frame
. Это может показаться запутанным, но на самом деле это очень полезно, а это значит, что вам никогда не придется настраивать contentSize
, но contentSize
будет автоматически настраиваться в соответствии с вашим контентом. Такое поведение описано в Technical Note TN2154.
Если вы хотите определить размер contentView
на экране или что-то в этом роде, вам нужно будет добавить ограничение между contentView
и основным видом, например. Это, по общему признанию, противоречиво для размещения контента в scrollview, поэтому я, вероятно, не советую этого, но это можно сделать.
Чтобы проиллюстрировать эту концепцию, что размер 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
of 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]];
Существует known issue (bug?) с многострочными этикетками в scrollviews, что если вы хотите, чтобы изменить размер в зависимости от количества текста, вы должны сделать некоторую ловкость рук, такими как:
dispatch_async(dispatch_get_main_queue(), ^{
randomLabel.preferredMaxLayoutWidth = self.view.bounds.size.width;
});
Я не могу показаться, чтобы получить ярлык расширить вертикально, если текст слишком длинный, чтобы поместиться на одна линия. Я установил количество строк в 0, а lineBreakMode - NSLineBreakByWordWrapping. Я что-то упускаю? – rdelmar
Кроме того, я добавил последнюю строку в вашем ответе, чтобы навести ширину contentView на ширину экрана (в противном случае ширина contentView будет достаточно широкой, чтобы разместить длинный текст). Если я явно устанавливаю высоту метки с ограничением высоты, то она работает. – rdelmar
Да, Мэтт обнаружил [пару обходов] (http://stackoverflow.com/questions/13149733/ios-autolayout-issue-with-uilabels-in-a-resizing-parent-view) для этой проблемы/ошибка многострочных меток. Я добавил один из них до конца моего ответа. Совершенно неудовлетворительное решение. Похоже, вам нужно выбирать между значениями жесткого кодирования или обходным путем. – Rob