以编程方式(没有 Storyboard),我试图删除一组约束并在设备旋转时创建一组新约束。我用来删除约束的代码执行时没有错误,但实际上并没有删除约束。当添加新的(冲突的)约束集时,这会导致布局错误。
我正在使用没有 Storyboard的 Xcode 10.1 和 Swift 4.2。在我的 MainViewController 中,我通过 viewDidLoad()
调用的函数创建并放置了一个名为“ticketsView”的 UICollectionView。在 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 个约束将被删除,以便我可以使用不同的值重新创建它们。我似乎找不到删除它们的方法(有效)。上面代码中注释掉的上面两行是为了表明我也尝试过(不成功)。
最佳答案
你可以试试
var portrait = [NSLayoutConstraint]()
var landscape = [NSLayoutConstraint]()
let porCon1 = ticketsView.leadingAnchor.constraint(equalTo: safe.trailingAnchor, constant: -safe.layoutFrame.width)
let porCon2 = ticketsView.trailingAnchor.constraint(equalTo:safe.trailingAnchor, constant: 0 )
let porCon3 = ticketsView.bottomAnchor.constraint(equalTo: safe.bottomAnchor, constant: 0)
let porCon4 = ticketsView.heightAnchor.constraint(equalToConstant: safe.layoutFrame.height * 0.75)
portrait = [porCon1,porCon2,porCon3,porCon4]
let landCon1 = ticketsView.leadingAnchor.constraint(equalTo: safe.trailingAnchor, constant: -safe.layoutFrame.width)
let landCon1 = ticketsView.trailingAnchor.constraint(equalTo:safe.trailingAnchor, constant: 0 )
let landCon1 = ticketsView.bottomAnchor.constraint(equalTo: safe.bottomAnchor, constant: 0)
let landCon1 = ticketsView.heightAnchor.constraint(equalToConstant: safe.layoutFrame.height * 0.65)
landscape = [landCon1,landCon2,landCo3,landCon4]
func setPortrait(_ por:Bool) {
portrait.forEach { $0.isActive = por }
landscape.forEach { $0.isActive = !por }
}
也可以
NSLayoutConstraint.deActivate(portrait)
NSLayoutConstraint.deActivate(landscape)
if por {
NSLayoutConstraint.activate(portrait)
}
else {
NSLayoutConstraint.activate(landscape)
}
关于ios - 如何解决我的 UICollectionView 的 "removeConstraint() not working"问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55554323/