У меня есть несколько вопросов об ограничениях макета / лучших методах привязки ...
Резюме
- Я хотел бы узнать о наилучшей практикеи, возможно, некоторые объяснения, где создавать экземпляры ограничений, которые ссылаются на части родительского представления.Я вижу, что viewDidLoad не годится
- Какие альтернативы viewDidLoad имеют смысл
- Но также, куда его поместить или что установить, поэтому он вызывается при обновлении вращения (некоторые постоянные значения являются сложнымирасчеты, основанные на заданной ширине и количестве элементов, и мне нужно затем пересчитать)
- Нужно ли мне сохранять все свои ограничения в свойствах и ссылаться на них при обновлении или я могу вызывать
self.view.leadingAnchor.constraint(equalTo: parentController.view.leadingAnchor,[..])
снова и снова
Мои настройки
В моем коде у меня есть вложенная иерархия, подобная этой
rootController
view
menuViewController
view
menuOneViewController
view
UIButton1
UIButton2
...
UIButton6
Каждый уровень имеет ограничения вЧто касается привязок родительского уровня.
Я начал с добавления ограничений в метод viewDidLoad каждого контроллера.
menuViewController:
override func viewDidLoad() {
super.viewDidLoad()
self.menuOneViewController = MenuOneViewController()
guard let menuOneViewController = self.menuOneViewController else { return }
menuOneViewController.parentController = self
self.view.addSubview(menuOneViewController.view)
}
menuOneViewController:
override func viewDidLoad() {
super.viewDidLoad()
guard let parentController = self.parentController else { return }
let menuRowHeight = parentController.menuRowHeight
self.view.heightAnchor.constraint(equalToConstant: menuRowHeight).isActive = true
self.view.leadingAnchor.constraint(equalTo: parentController.view.leadingAnchor, constant: 0).isActive = true
self.view.trailingAnchor.constraint(equalTo: parentController.view.trailingAnchor, constant: 0).isActive = true
self.view.topAnchor.constraint(equalTo: parentController.view.topAnchor, constant: -(menuRowHeight)).isActive = true
И с этой настройкой я получил это сообщение:
'Unable to activate constraint with anchors
<NSLayoutXAxisAnchor:0x600001199900 "UIView:0x7fd99e705b90.leading">
and <NSLayoutXAxisAnchor:0x600001199980 "UIView:0x7fd99e526bc0.leading">
because they have no common ancestor. Does the constraint or its
anchors reference items in different view hierarchies? That's illegal.'
Myмысли и детали
И я думаю, я понял ... Я думаю, что иерархия еще не построена в методе viewDidLoad.Я предполагаю, что это происходит после viewDidLoad (), поэтому мне нужно было бы либо перенести такие ограничения в метод в дочернем элементе, который вызывается после viewDidLoad, либо я мог бы создать ограничения в родительском объекте после вызова addSubview.
Теперь, хотя последний способ будет работать наверняка, я все же хотел бы знать, в каком другом месте я бы его обычно ставил.А также я бы предпочел не беспокоить родительский контроллер представления логикой того, насколько большим должно быть представление дочерних контроллеров представления.
Так я бы тогда поместил такой код в updateViewConstraints
?потому что если это так, то он, кажется, не вызывается при ротации, что было моей следующей заботой, или мне нужно установить некоторые флаги или сделать что-то еще.чтобы это срабатывало вручную.Если да, то какой метод ?, на каком уровне?
Кроме того, если этот метод будет вызван дважды, у меня возникнут проблемы из-за повторной генерации ограничений / дублирования конфликтующих ограничений?Какова лучшая практика в этом случае?
Также в этом отношении имеет ли какое-либо значение, если я использую NSLayoutConstraint(item: view, [..]).isActive = true
против view.anchor.constraint(
Я впервые узнал о NSLayoutConstraint, затем одругие способы (якоря и язык визуального формата), и прямо сейчас у меня есть смесь anchor.constraints и NSLayoutConstraint, не уверенный, какой путь пойти.Но так как мне нравится мой чистый код, я бы хотел придерживаться одного способа.