Я считаю, что это лучший способ изменить значения Storyboard NSLayoutConstraint IBOutlets таким образом, чтобы это изменение сохраняло изменения класса ориентации / размера.
Я определил в раскадровке ограничение с включенными установленными свойствами для некоторых классов размеров, например.Обычный / Компактный, и выключите для других классов размера, таких как Компактный / Обычный.
Я могу изменить значение этого ограничения из кода через IBOutlet в viewDidAppear (), но оно работает только до тех пор, пока я не поверну устройство.После того, как ограничение поворота устройства будет удалено, затем снова переустановится со старым значением раскадровки (или, если деактивировано в коде, просто снова активируется).
Поэтому я попытался добавить дополнительную модификацию в метод traitCollactionDidChange ().НО это не работает, оно вызывается до того, как будут установлены значения ограничений Stroyboard!Поэтому моя модификация перезаписывается значением, определенным в раскадровке.
Затем я попробовал viewDidLayoutSubviews () (UIViewController) или layoutSubviews () (UIView).В случае простого представления это, кажется, работает, но это было ненадежно, если я добавил больше модификаций представлений, чем вычисления повисли у меня при повороте.
Таким образом, в качестве последнего средства я добавил Timer.scheduledTimer () с задержкой в 1 секунду к traitCollectionDidChange (), это, похоже, работает, но также может показаться странным взломом.Что, если раскадровка устанавливает значения ограничений через одну секунду, возможно, Apple что-то изменит в следующих версиях Swift / iOS.Могу ли я передать такой взлом?
Мой код:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if UIDevice.current.userInterfaceIdiom == .pad {
bottomConstraint.isActive = false
} else if traitCollection.sizeClasses == (.regular, .compact) {
iphoneLeadingSpacerProportionalWidth = leadingSpacerProportionalWidth.setMultiplier(multiplier: 0.1)
iphoneTrailingSpacerProportionaWidth = trailingSpacerProportionalWidth.setMultiplier(multiplier: 0.1)
}
}
private var iphoneLeadingSpacerProportionalWidth : NSLayoutConstraint? = nil
private var iphoneTrailingSpacerProportionaWidth : NSLayoutConstraint? = nil
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if let leadingConstraint = iphoneLeadingSpacerProportionalWidth,
let trailingConstraint = iphoneTrailingSpacerProportionaWidth {
NSLayoutConstraint.deactivate([leadingConstraint, trailingConstraint])
}
Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { (timer) in
if UIDevice.current.userInterfaceIdiom == .pad {
self.bottomConstraint.isActive = false
} else if self.traitCollection.sizeClasses == (.regular, .compact) {
self.iphoneLeadingSpacerProportionalWidth = self.leadingSpacerProportionalWidth.setMultiplier(multiplier: 0.1)
self.iphoneTrailingSpacerProportionaWidth = self.trailingSpacerProportionalWidth.setMultiplier(multiplier: 0.1)
}
}
}
Внимание!Этот setMultiplier () использует найденное мной расширение, поэтому не обращайте на него внимания, оно работает так же, если я установлю constraint.constant = toSomeValue