Ответ 1
Я внимательно прочитал документы Apple о том, как UIScrollView
работает с автоматической разметкой.
-
Во-первых, вам не нужно создавать представление с искусственным контентом, вы можете добавлять подпредставления непосредственно в представление с прокруткой (и я предпочитаю это, поскольку считаю представление с искусственным контентом посторонним и ненужным объектом). Apple не рекомендует создавать один, они только предлагают, что вы можете.
-
Во-вторых, подпредставления представления прокрутки не должны полагаться на представление прокрутки, чтобы определить их размеры, только их положения.
-
И в-третьих, ваши ограничения должны определять самые левые, самые правые, самые верхние и самые нижние края, чтобы автоматическое расположение создавало представление контента для вас. Поначалу это правило может показаться нелогичным, но именно так Apple хочет, чтобы вы создали представление прокрутки.
В частности, когда вы создаете представление прокрутки, вы можете дать его фрейму границы представления контроллера:
scrollView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(scrollView)
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
scrollView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
scrollView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
Затем необходимо установить границы представления содержимого, привязав его подпредставления к краям представления прокрутки. Поэтому ваш самый верхний вид должен быть привязан к вершине вида с прокруткой, и его ширина не может превышать ширину вида с прокруткой (который является шириной вида) (если ваша цель - прокрутка только по вертикали).
topMostView.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(topMostView)
topMostView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
topMostView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
topMostView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
topMostView.heightAnchor.constraint(equalToConstant: 1000).isActive = true
Обратите внимание, что topMostView
не использует представление прокрутки для определения его размера (только его положение) - это важно.
Содержание в вашем представлении прокрутки теперь имеет высоту 1000
но оно не будет прокручиваться, потому что ничто не привязано к нижней части представления прокрутки. Поэтому сделайте это в своем самом нижнем представлении.
bottomMostView.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(bottomMostView)
bottomMostView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
bottomMostView.topAnchor.constraint(equalTo: topMostView.bottomAnchor).isActive = true
bottomMostView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
bottomMostView.heightAnchor.constraint(equalToConstant: 1000).isActive = true
bottomMostView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
Последний якорь может показаться странным, потому что вы привязываете представление, которое имеет высоту 1000
пунктов, к якору, который вы только что прикрепили к нижней части вида, который определенно имеет высоту менее 1000
пунктов. Но именно так Apple хочет, чтобы вы это сделали. Таким образом, вам не нужно создавать представление контента, авто макет сделает это за вас. И вы, конечно, можете по-прежнему получать доступ к измерениям представления содержимого из свойств представления прокрутки как обычно.
Кстати, этот принцип определения "краевых ограничений" (самый левый, самый правый, самый верхний, самый нижний) выходит за рамки прокрутки. Когда вы создаете пользовательский UITableViewCell
с помощью автоматического макета, определяете четыре граничных ограничения (т. topMostView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
привязано к верхней части ячейки topMostView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
, bottom Самое нижнее представление в нижней части ячейки bottomMostView.topAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
и т.д.) - это способ создания ячеек с bottomMostView.topAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
. Это то, как вы создаете что-либо для себя, например, представления, элементы управления и т.д.