Ключом к тому, чтобы заставить представления прокрутки работать с автоматическим макетом, является обеспечение полной «цепочки» вертикальных ограничений и высот элементов, а также горизонтальных ограничений и ширины элементов.
Вот примерто, о чем я думаю вы собираетесь (зеленая "8-пунктовая горизонтальная линия", которую вы видите, это цвет фона scrollView, который вы видите, потому что между topView
и 8-pt
имеется вертикальное ограничениеbottomView
):
«Нижний» серый вид имеет высотуограничение 500-pts
, поэтому мы можем прокрутить вверх:
Вот код для создания этого:
-(void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIScrollView *scrollView = [UIScrollView new];
UIView *topView = [UIView new];
UIView *bottomView = [UIView new];
UITextView *textView = [UITextView new];
UIStackView *stackView1 = [UIStackView new];
UIStackView *stackView2 = [UIStackView new];
scrollView.backgroundColor = [UIColor greenColor];
topView.backgroundColor = [UIColor redColor];
bottomView.backgroundColor = [UIColor lightGrayColor];
self.view.backgroundColor = [UIColor yellowColor];
scrollView.translatesAutoresizingMaskIntoConstraints = false;
topView.translatesAutoresizingMaskIntoConstraints = false;
bottomView.translatesAutoresizingMaskIntoConstraints = false;
textView.translatesAutoresizingMaskIntoConstraints = false;
stackView1.translatesAutoresizingMaskIntoConstraints = false;
stackView2.translatesAutoresizingMaskIntoConstraints = false;
// don't bounce the scroll view
scrollView.bounces = false;
// we want the textView to auto-size its height, so set it to non-scrolling
textView.scrollEnabled = NO;
// slightly bigger than default font
textView.font = [UIFont systemFontOfSize:18.0];
// stackView properties
stackView1.axis = UILayoutConstraintAxisVertical;
stackView2.axis = UILayoutConstraintAxisVertical;
stackView1.spacing = 5;
stackView1.distribution = UIStackViewDistributionFill;
stackView2.spacing = 5;
stackView2.distribution = UIStackViewDistributionFill;
// add the scrollView to the view
[self.view addSubview:scrollView];
// constrain scroll view to all 4 sides
[NSLayoutConstraint activateConstraints:
@[
[scrollView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
[scrollView.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor],
[scrollView.leadingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leadingAnchor],
[scrollView.trailingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.trailingAnchor]
]
];
// add textView and both stack views to topView
[topView addSubview:textView];
[topView addSubview:stackView1];
[topView addSubview:stackView2];
// setup constraints for topView's subviews
[NSLayoutConstraint activateConstraints:
@[
// textView top, leading and trailing to topView with 8-pts "padding"
[textView.topAnchor constraintEqualToAnchor:topView.topAnchor constant:8.0],
[textView.leadingAnchor constraintEqualToAnchor:topView.leadingAnchor constant:8.0],
[textView.trailingAnchor constraintEqualToAnchor:topView.trailingAnchor constant:-8.0],
// textView should be *at least* 200-pts tall, getting taller if enough text is added
[textView.heightAnchor constraintGreaterThanOrEqualToConstant:200.0],
// stackView1 top to text view bottom, leading and trailing to topView with 8-pts "padding"
[stackView1.topAnchor constraintEqualToAnchor:textView.bottomAnchor constant:8.0],
[stackView1.leadingAnchor constraintEqualToAnchor:topView.leadingAnchor constant:8.0],
[stackView1.trailingAnchor constraintEqualToAnchor:topView.trailingAnchor constant:-8.0],
// stackView2 top to stackView1 bottom, leading and trailing to topView with 8-pts "padding"
[stackView2.topAnchor constraintEqualToAnchor:stackView1.bottomAnchor constant:8.0],
[stackView2.leadingAnchor constraintEqualToAnchor:topView.leadingAnchor constant:8.0],
[stackView2.trailingAnchor constraintEqualToAnchor:topView.trailingAnchor constant:-8.0],
// and constrain stackView2 to bottom of topView with 8-pts padding
[stackView2.bottomAnchor constraintEqualToAnchor:topView.bottomAnchor constant:-8.0],
]
];
// now let's add some labels to the stack views
int numLabels = arc4random_uniform(3) + 2;
for (int i = 0; i < numLabels; i++){
UILabel *label = [UILabel new];
label.font = [UIFont systemFontOfSize:20];
label.numberOfLines = 0;
label.translatesAutoresizingMaskIntoConstraints = false;
label.backgroundColor = [UIColor cyanColor];
label.text = [NSString stringWithFormat:@"Label %d\nIn stackView 1 \nwith more than one line", i];
[stackView1 addArrangedSubview:label];
}
numLabels = arc4random_uniform(3) + 2;
for (int i = 0; i < numLabels; i++){
UILabel *label = [UILabel new];
label.font = [UIFont systemFontOfSize:20];
label.numberOfLines = 0;
label.translatesAutoresizingMaskIntoConstraints = false;
label.backgroundColor = [UIColor colorWithRed:1.0 green:0.75 blue:0.5 alpha:1.0]; // light-orange
label.text = [NSString stringWithFormat:@"Label %d\nIn stackView 2 \nwith more than one line", i];
[stackView2 addArrangedSubview:label];
}
// add topView and bottomView to the scrollView
[scrollView addSubview:topView];
[scrollView addSubview:bottomView];
// setup topView and bottomView's constraints
[NSLayoutConstraint activateConstraints:
@[
// topView top, leading, trailing and width to scrollView
[topView.topAnchor constraintEqualToAnchor:scrollView.topAnchor constant:0.0],
[topView.leadingAnchor constraintEqualToAnchor:scrollView.leadingAnchor constant:0.0],
[topView.trailingAnchor constraintEqualToAnchor:scrollView.trailingAnchor constant:0.0],
[topView.widthAnchor constraintEqualToAnchor:scrollView.widthAnchor constant:0.0],
// bottomView top to topView bottom (8-pts padding), leading, trailing, width to scrollView
[bottomView.topAnchor constraintEqualToAnchor:topView.bottomAnchor constant:8.0],
[bottomView.leadingAnchor constraintEqualToAnchor:scrollView.leadingAnchor constant:0.0],
[bottomView.trailingAnchor constraintEqualToAnchor:scrollView.trailingAnchor constant:0.0],
[bottomView.widthAnchor constraintEqualToAnchor:scrollView.widthAnchor constant:0.0],
// and bottom of bottomView to bottom of scrollView
[bottomView.bottomAnchor constraintEqualToAnchor:scrollView.bottomAnchor constant:0.0],
// bottomView has no subviews to provide a height, so constrain it to 500-pts tall
[bottomView.heightAnchor constraintEqualToConstant:500.0],
]
];
}
Примечание: мне гораздо легче - особенно во время макетов проектирования / отладки - группировать связанные задачи вместе.Итак, в этом коде вы увидите группировки для:
- просмотра экземпляров
- просмотра настроек свойств
addSubview()
действий - ограничениянастройки
Редактировать: пара изменений, сделанных, чтобы отразить требование, чтобы textView было как минимум 200-поддержки высоты (с использованием ограничения greaterThanOrEqualTo
).