Программно (без раскадровок) я пытаюсь удалить один набор ограничений и создать новый набор всякий раз, когда устройство поворачивается. Код, который я использую для удаления ограничений, выполняется без ошибок, но фактически не удаляет ограничения. Это приводит к ошибке макета при добавлении нового набора (конфликтующих) ограничений.
Я использую Xcode 10.1 и Swift 4.2 без раскадровок. В моем MainViewController я создаю и размещаю UICollectionView с именем «ticketsView» из функций, вызываемых viewDidLoad()
. После addChild()
и addSubview()
я вызываю функцию с именем applyTicketsViewConstraints()
, которая определяет текущую ориентацию устройства, а затем (как ожидается) удаляет все существующие ограничения и применяет соответствующий набор ограничений для текущей ориентации устройства.
Я переопределяю viewWillTransition:toSize:withCoordinator()
, который вызывает одну и ту же функцию applyTicketsViewConstraints()
из замыкания координатора при каждом повороте устройства.
При запуске приложения ограничения корректно применяются на основе исходной ориентации устройства. При первом повороте устройства на 90 градусов дисплей также успешно изменяется, но любое вращение после этого приводит к сообщению об ошибке «[LayoutConstraints] Невозможно одновременно удовлетворить ограничения».
Я попытался перебрать существующие ограничения ticketsView и удалить их по одному, и я попытался удалить их все сразу, но ни один из подходов не приводит к фактическому удалению ограничений. Похоже, они оба работают успешно, но после их завершения ограничения остаются в силе.
func createTicketCollectionWindow() {
ticketsLayout = UICollectionViewFlowLayout()
ticketsVC = TicketCollectionController(collectionViewLayout: ticketsLayout)
ticketsVC?.collectionView?.backgroundColor = UIColor.darkGray
ticketsView = ticketsVC!.view
ticketsView.translatesAutoresizingMaskIntoConstraints = false
addChild(ticketsVC!)
self.view.addSubview(ticketsView)
applyTicketsViewConstraints()
}
func applyTicketsViewConstraints() {
let safe = self.view.safeAreaLayoutGuide
let deviceSize = UIScreen.main.bounds.size
for individualConstraint in ticketsView.constraints {
print("TicketViewConstraints: Removing Constraint: \(individualConstraint)" )
// ticketsView.removeConstraint(individualConstraint)
}
ticketsView.removeConstraints(ticketsView.constraints)
// self.view.removeConstraints(ticketsView.constraints)
if deviceSize.width < deviceSize.height {
print("TicketsView Constraint: Device is in PORTRAIT orientation!")
ticketsView.leadingAnchor.constraint(equalTo: safe.trailingAnchor, constant: -safe.layoutFrame.width).isActive = true
ticketsView.trailingAnchor.constraint(equalTo:safe.trailingAnchor, constant: 0 ).isActive = true
ticketsView.bottomAnchor.constraint(equalTo: safe.bottomAnchor, constant: 0).isActive = true
ticketsView.heightAnchor.constraint(equalToConstant: safe.layoutFrame.height * 0.75).isActive = true
} else {
print("TicketsView Constraint: Device is in LANDSCAPE orientation!")
ticketsView.leadingAnchor.constraint(equalTo: safe.trailingAnchor, constant: -safe.layoutFrame.width).isActive = true
ticketsView.trailingAnchor.constraint(equalTo:safe.trailingAnchor, constant: 0 ).isActive = true
ticketsView.bottomAnchor.constraint(equalTo: safe.bottomAnchor, constant: 0).isActive = true
ticketsView.heightAnchor.constraint(equalToConstant: safe.layoutFrame.height * 0.65).isActive = true
}
ticketsView.layoutIfNeeded()
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: { (_) in
self.applyTicketsViewConstraints()
self.ticketsVC?.collectionView.reloadData()
}) { (_) in
self.ticketsView.layoutIfNeeded()
}
}
Я ожидаю, что 4 ограничения, которые я создаю в приведенном выше коде, будут удалены, чтобы я мог воссоздать их с другими значениями. Я не могу найти способ удалить их (это работает). Две строки выше, которые закомментированы в приведенном выше коде, показывают, что я также попробовал их (безуспешно).