我试图通过以编程方式操作约束来“显示”和“隐藏” Collection View 。
我的应用程序是用代码编写的,没有使用 Storyboard或@IBOutlets。
第一次按下按钮时, Collection View 会按预期正确显示。
第二次按下按钮时, Collection View 只是保持在原位,不会“隐藏”。
openMenu
代码中的打印语句确认正在调用每个约束 block 。即:我收到“打开”和“关闭”的控制台消息。
创建 Collection View 没有问题,只是以编程方式设置约束不会关闭菜单。
我的代码如下...
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.isNavigationBarHidden = false
view.backgroundColor = .white
view.addSubview(bgImageView)
view.addSubview(myListCV)
}
lazy var myListCV: UICollectionView = {
let myListLayout = UICollectionViewFlowLayout()
myListLayout.itemSize = CGSize(width: 200, height: 40)
myListLayout.minimumLineSpacing = 1
myListLayout.sectionHeadersPinToVisibleBounds = true
let myListView = UICollectionView(frame: .zero, collectionViewLayout: myListLayout)
myListView.translatesAutoresizingMaskIntoConstraints = false
myListView.delegate = self
myListView.dataSource = self
myListView.bounces = false
myListView.alwaysBounceVertical = false
myListView.showsVerticalScrollIndicator = true
myListView.backgroundColor = UIColor(r: 203, g: 203, b: 203)
return myListView
}()
var menuShowing = false
func openMenu() {
if (menuShowing) {
print("closed")
myListCV.leftAnchor.constraint(equalTo: view.rightAnchor).isActive = true
myListCV.topAnchor.constraint(equalTo: view.topAnchor, constant: 64).isActive = true
myListCV.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
myListCV.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
} else {
print("open")
myListCV.leftAnchor.constraint(equalTo: view.rightAnchor, constant: -200).isActive = true
myListCV.topAnchor.constraint(equalTo: view.topAnchor, constant: 64).isActive = true
myListCV.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
myListCV.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
}
menuShowing = !menuShowing
}
最佳答案
上述代码的问题在于,每次用户打开或关闭该部分时,您都会不断地设置约束,因此根据用户执行此操作的次数,您最终会得到数百个约束需要。
您应该做的是设置默认状态的约束(我假设在本例中是关闭的),并将您希望更改的约束存储在属性中。然后,您可以简单地调整此约束的常量来显示/隐藏菜单。
例如
private var myListCVLeftConstraint: NSLayoutConstraint?
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.isNavigationBarHidden = false
view.backgroundColor = .white
view.addSubview(bgImageView)
self.configMyListCV()
}
lazy var myListCV: UICollectionView = {
let myListLayout = UICollectionViewFlowLayout()
myListLayout.itemSize = CGSize(width: 200, height: 40)
myListLayout.minimumLineSpacing = 1
myListLayout.sectionHeadersPinToVisibleBounds = true
let myListView = UICollectionView(frame: .zero, collectionViewLayout: myListLayout)
myListView.translatesAutoresizingMaskIntoConstraints = false
myListView.delegate = self
myListView.dataSource = self
myListView.bounces = false
myListView.alwaysBounceVertical = false
myListView.showsVerticalScrollIndicator = true
myListView.backgroundColor = UIColor(r: 203, g: 203, b: 203)
return myListView
}()
var menuShowing = false
private func configMyListCV() -> Void {
view.addSubview(myListCV)
self.myListCV.topAnchor.constraint(equalTo: view.topAnchor, constant: 64).isActive = true
self.myListCV.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
self.myListCV.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
self.myListCVLeftConstraint = myListCV.leftAnchor.constraint(equalTo: view.rightAnchor)
self.myListCVLeftConstraint.isActive = true
}
func openMenu() {
if (menuShowing) {
self.myListCVLeftConstraint?.constant = 0.0
} else {
self.myListCVLeftConstraint?.constant = -200.0
}
menuShowing = !menuShowing
}
这对于这个简单的用户案例来说效果很好;但是,如果您将来要做更深入的事情,我建议在 View 上设置多个约束,并根据需要禁用/启用所需的约束。
关于Swift - 以编程方式更改约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45852446/