#swift #uistackview #viewdidlayoutsubviews
Вопрос:
Итак , у меня есть а scrollView
, внутри которого scrollView
находится а stackView
, содержащее все views
на экране.
Проблема в том, что у меня stackView
много скрытых возможностей views
, поэтому мне нужно настроить свою containsVieww's height
базу на своем stackView's height
мой код питания должен быть таким :
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
print(stackView.bounds.height)
// do logic to change contentView size here
}
func setupView(){
scrollView.topAnchor.constraint(equalTo: guide.topAnchor).isActive = true
scrollView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
scrollView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
scrollView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
scrollView.backgroundColor = .white
scrollView.contentSize = CGSize(width: view.frame.width, height: view.frame.height)
scrollView.addSubview(stackView)
stackView.setArrangedSubView(views: [label1, label 2, label 3, label 4, ..., label n]
[label1, label 2, label 3].isHidden = true
}
func onHitButton(){
if isHidden {
[label1, label 2, label 3].isHidden = false
isHidden = false
} else {
[label1, label 2, label 3].isHidden = true
isHidden = true
}
print(stackView.bounds.height) // still return the ex height
}
Вот в чем проблема:
На первом init
, мой [label1,2,3].isHidden = true
, мой stackViewHeight
это 500
Когда мой onHitButton
вызывается, мой [label1,2,3].isHidden = false
, мой stackViewHeight
по-прежнему 500
, но экран отображается правильно, теперь они labels
видны, а мой stackView
растянут. И, конечно, мой scrollView
is отображается неправильно.
Затем я onHitButton
снова нажал «мои», они labels
скрыты, мои stackView
уменьшаются на экране, но stackViewHeight
возвращенные 850
?
Все должно быть наоборот.
Я также попытался print
height
button
позвонить по другому телефону, и он вернул право height
? Похоже viewDidLayoutSubviews
, позвонили слишком рано.
Подводя итог: stackView
верните высоту, прежде чем она сама изменит свой размер
Ответ №1:
Используйте автоматическую компоновку, чтобы ограничить представление стека Руководством по компоновке содержимого представления прокрутки:
scrollView.addSubview(stackView)
stackView.translatesAutoresizingMaskIntoConstraints = false
// reference to scrollView's Content Layout Guide
let cGuide = scrollView.contentLayoutGuide
// reference to scrollView's Frame Layout Guide
let fGuide = scrollView.frameLayoutGuide
NSLayoutConstraint.activate([
// constrain stackView to scrollView's Content Layout Guide
stackView.topAnchor.constraint(equalTo: cGuide.topAnchor),
stackView.leadingAnchor.constraint(equalTo: cGuide.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: cGuide.trailingAnchor),
stackView.bottomAnchor.constraint(equalTo: cGuide.bottomAnchor),
// constrain stackView's Width to scrollView's Frame Layout Guide
stackView.widthAnchor.constraint(equalTo: fGuide.widthAnchor),
])
Это полностью избавит вас от необходимости когда-либо устанавливать .contentSize
-все это будет обрабатываться автоматической компоновкой.
Комментарии:
1. зачем вам давать ведущий и задний якорь, почему уже есть широкий якорь? Кроме этого, все работает идеально. Спасибо
2. Еще одна незначительная проблема, которую я обнаружил, заключается в том, что, похоже, я не могу настроить константу bottomAnchor, нижняя часть моего последнего представления в StackView всегда находится в поле зрения. Дно без какого-либо пространства. Я пытался указать константу как в нижнем окне StackView, так и в нижнем окне ScrollView, но это не сработало . Но давать
topAnchor constant
работу. Странный3. Ведущие / Задние / Якоря Ширины … именно так работают представления прокрутки. Начальная и конечная Ширина определяет размер горизонтальной прокрутки, Верхняя и Нижняя Высота определяет размер вертикальной прокрутки. Здесь мы используем содержимое представления стека (упорядоченные подвиды) для определения его высоты. Прокомментируйте линию ограничения ширины и посмотрите, что вы получите. Затем попробуйте установить константу ограничения ширины на 100, или 500, или 1000 и посмотрите, что вы получите.
4. «мой последний вид в StackView всегда на виду. Дно без какого-либо пространства» … Вы имеете в виду, что вам нужно некоторое «пустое пространство» после нижней части представления стека? Если это так, дайте отрицательное значение для постоянной нижнего якоря. Например:
stackView.bottomAnchor.constraint(equalTo: cGuide.bottomAnchor, constant: -100.0),