Установка ограничений в viewWillAppear - PullRequest
0 голосов
/ 21 февраля 2019

У меня есть uiview в центре viewcontroller.Существует uilabel выше (A) и ниже (B) этого uiview.

Я хочу программно изменить нижнее ограничение этого uiview, чтобы расстояние выше и ниже uiviewравны друг другу при изменении размера экрана.Таким образом, рассчитывается расстояние между верхом uiview до низа uilabel (A) и расстоянием между низом uiview до верха uilabel (B), делится на 2 и затем устанавливается константа нижнего ограничения соответственно.

Я выполнил расчет, но кажется, что он работает, только когда я помещаю его в viewDidAppear, и мне нужно, чтобы ограничения и представления были на своем месте, прежде чем пользователь сможет увидеть объекты.Возможно ли это сделать в viewWillAppear.мне кажется, что все элементы не установлены до viewDidAppear, чтобы я мог правильно рассчитать ... я считаю, что это связано с жизненным циклом autolayout, не завершенным до расчета ..

let topDistance = view.frame.minY - ALabel.frame.maxY
    let bottomDistance = BLabel.frame.minY - view.frame.maxY
    let total = topDistance + bottomDistance
    bottomConstraint.constant = total / 2

Ниже приведен пример желаемого результата до / после, когда фиолетовый цвет uiview имеет нижнее ограничение для нижнего оранжевого цвета uilabel.например, когда размер экрана увеличивается по длине, я хочу, чтобы нижнее ограничение имело ту же константу, что и расстояние между фиолетовым uiview и верхним оранжевым uilabel.Верхняя часть uilabel имеет верхнее ограничение сверху, а нижняя uilabel - нижнее ограничение снизу.Example

Ответы [ 5 ]

0 голосов
/ 22 февраля 2019

Чтобы попытаться ответить на ваш вопрос:

Вы правы, этот автоматический макет не закончил свою работу в viewDidLoad() или даже viewWillAppear().Обычно, когда вам нужно выполнить такие настройки макета, вы должны сделать это в viewDidLayoutSubviews().Из документов Apple:

viewDidLayoutSubviews

Когда изменяются границы для представления контроллера представления, представление корректирует позиции своих подпредставлений, а затем система вызывает этометод.

Однако, если я понимаю, что вы на самом деле пытаетесь сделать ...

Используя UIStackView, вы можете избежать необходимости использовать any код.

Вставьте ваши метки, виды, кнопки и т. Д. В вертикальное значение UIStackView.Задайте для свойств:

Alignment: Fill   (or Leading or Center as suits your layout)
Distribution: Equal Spacing
Spacing: 0

Ограничить верхнюю часть стекового представления к верху представления (плюс любое желаемое заполнение) и от нижнего до нижнего представления (плюс любое желаемое заполнение).

Результат с размером iPhone SE:

enter image description here

Результат с размером iPhone 8:

enter image description here

Результат с размером iPhone XS:

enter image description here

А вот iPhone 8 с парой дополнительных элементов различной высоты:

enter image description here

Как видите, элементы имеют одинаковое вертикальное расстояние между ними, и все это обрабатывается стековым представлением.

0 голосов
/ 21 февраля 2019

Для этого вы можете использовать Очередь отправки:

      DispatchQueue.main.async {
          let topDistance = view.frame.minY - ALabel.frame.maxY
          let bottomDistance = BLabel.frame.minY - view.frame.maxY
          let total = topDistance + bottomDistance
          bottomConstraint.constant = total / 2
         self.view.layoutIfNeeded()
    }
0 голосов
/ 21 февраля 2019

Когда вы используете View, он уже появился, когда пользователь видит VeiwController. Вместо этого используйте viewDidLoad, вы не можете использовать viewWillAppear, потому что View еще не загружен.

Используйте его на:

override func viewDidLoad() {
    super.viewDidLoad()
}

И вы можете попробовать позвонить

self.view.layoutIfNeeded()
0 голосов
/ 21 февраля 2019

Когда я хочу установить ограничения программно, я обычно поступаю так:

let v = UIView()
v.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(v)
v.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 20).isActive = true
v.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -20).isActive = true
v.heightAnchor.constraint(equalToConstant: 100).isActive = true
v.centerYAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerYAnchor).isActive = true
0 голосов
/ 21 февраля 2019

Запись layoutIfNeeded после ограничения обновления.

let topDistance = view.frame.minY - ALabel.frame.maxY
let bottomDistance = BLabel.frame.minY - view.frame.maxY
let total = topDistance + bottomDistance
bottomConstraint.constant = total / 2
self.view.layoutIfNeeded()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...