Search code examples
iosswiftuiviewuicollectionviewios-animations

UICollectionView show hide animation issue


I am getting animation issue while hiding the UICollectionView. Show animation works fine but when I do the hide animation, it immediately hides the collection view without animation. This is the code :

@objc func openMenu(sender: UIButton) {
        if sender.tag == 1 {
            self.buttonView.tag = 2
            self.arrow.image = UIImage(named: "arrowUp.png")
            UIView.animate(withDuration: 0.7, animations: {
                self.moduleView.frame.size.height = UIScreen.main.bounds.size.height - self.frame.size.height
            }, completion: { _ in
            })
        } else {
            self.buttonView.tag = 1
            self.arrow.image = UIImage(named: "arrowDown.png")
            UIView.animate(withDuration: 0.7, animations: {
                self.moduleView.frame.size.height = 0
            }, completion: { _ in
            })
        }
    }  

Output :

enter image description here

The strange thing is, I replaced the collection view with a simple UIView and it works fine. Bottom to top animation works perfectly. Code :

@objc func openMenu(sender: UIButton) {
        if sender.tag == 1 {
            self.buttonView.tag = 2
            self.arrow.image = UIImage(named: "arrowUp.png")
            UIView.animate(withDuration: 0.7, animations: {
                self.testView.frame.size.height = UIScreen.main.bounds.size.height - self.frame.size.height
            }, completion: { _ in
            })
        } else {
            self.buttonView.tag = 1
            self.arrow.image = UIImage(named: "arrowDown.png")
            UIView.animate(withDuration: 0.7, animations: {
                self.testView.frame.size.height = 0
            }, completion: { _ in
            })
        }
    }  

Output :

enter image description here

Question : Why doesn't that work for UICollectionView ?

Initialisation :

UICollectionView :

self.moduleView = ModulesCollectionView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 0), collectionViewLayout: UICollectionViewLayout())  
self.parentView.addSubView(self.moduleView)  

UIView :

self.testView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 0))  
self.parentView.addSubView(self.testView)

Solution

  • You need to use layoutSubViews() method for proper animation. Please change your code as below :

    @objc func openMenu(sender: UIButton) {
        if sender.tag == 1 {
            self.buttonView.tag = 2
            self.arrow.image = UIImage(named: "arrowUp.png")
            UIView.animate(withDuration: 0.7, animations: {
                self.moduleView.frame.size.height = UIScreen.main.bounds.size.height - self.frame.size.height
                // Add this line
                self.moduleView.layoutSubviews()
            }, completion: { _ in
            })
        } else {
            self.buttonView.tag = 1
            self.arrow.image = UIImage(named: "arrowDown.png")
            UIView.animate(withDuration: 0.7, animations: {
                self.moduleView.frame.size.height = 0
                // Add this line
                self.moduleView.layoutSubviews()
            }, completion: { _ in
            })
        }
    }