Reputation: 93
I am trying to 'show' & 'hide' a collection view by manipulating the constraints programmatically.
My app is written in code, no storyboards or @IBOutlets are being used.
The first time I press the button, the collection view appears correctly and as expected.
The second time I press the button, the collection view just stays in place and does not 'hide'.
The print statements within the openMenu
code are confirming that each block of constraints is being called. ie: I get console messages for 'open' and 'closed'.
I don't have an issue with creating the collection view, it's just that setting the constraints programmatically does not close the menu.
My code is as follows...
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
}
Upvotes: 2
Views: 1623
Reputation: 420
The problem with your above code is that you are continually setting constraints every time the user opens or closes the the section, so depending on how many times the user does this you'll end up with hundreds of constrains that just aren't needed.
What you should do is set the constraints for the default state, I'm assuming closed in this instance, and store the constraint you wish to change in a property. You can then simply adjust the constant of this constraint to show/hide your menu.
e.g.
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
}
This will work well for this simple user case; however if you do anything more in depth in the future I'd suggest setting multiple constraints on the view and simply disable/enable the required ones as needed.
Upvotes: 3