Azat
Azat

Reputation: 590

UICollectionViewCell Animation With Protocol

Im trying to animate my menu which made with UICollectionView. I have 2 more collection view which you can see in the below.

Main Screen

And I'm trying to animate top bar when scrolled down. When animation is completed the "Pokemon" label will be white, the pokemon image will be hidden, and the background will be blue. I use protocol to reach cell. This is my ViewController class.

protocol TopCategoriesDelegator{
func openTopBar()
func closeTopBar()}

And this is cellForRowAt function

 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    if collectionView == self.collectionView{
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "topCategory", for: indexPath) as! TopCategoriesCell

        cell.viewController = self
        return cell
    }else if collectionView == subCategoriesCollectionView{
        return collectionView.dequeueReusableCell(withReuseIdentifier: "subCategories", for: indexPath)
    }else{
        return  collectionView.dequeueReusableCell(withReuseIdentifier: "productCell", for: indexPath)
    }
}

And for detection of scrolling down;

        func scrollViewDidScroll(_ scrollView: UIScrollView) {
//            print(scrollView.contentOffset.y)
        if scrollView.contentOffset.y > 160 {
                if self.cellDelegate != nil{
                    self.cellDelegate.closeTopBar() // func in main vc for background color and size
                    closeAnimation()
                }
        }else{
                if self.cellDelegate != nil{
                    self.cellDelegate.openTopBar() // func in main vc for background color and size
                    openAnimation()
                }
        }
    }

And this is the TopCategoriesCell class

override func layoutSubviews() {

    if let vc = viewController as? ProductsVC{
        vc.cellDelegate = self
    }
}
func closeTopBar() {
    UIView.animate(withDuration: 0.3) {
       self.categoryImage.frame = CGRect(x: 0, y: 0, width: 0, height: 0)
       self.categoryImage.isHidden = true
    }
}
func openTopBar(){
    UIView.transition(with: categoryImage, duration: 0.3, options: .curveEaseIn, animations: {
        self.categoryImage.isHidden = false
        self.categoryName.textColor = UIColor().rgb(red: 37.0, green: 110.0, blue: 140.0)
    }, completion: nil)
}

Actually everything works fine. But only first element dissappear the others stays there like this;

MainVC After Animation

How can i hide other cell's images ?

Thank You.

Upvotes: 0

Views: 302

Answers (1)

Pranav Kasetti
Pranav Kasetti

Reputation: 9935

You have set the cell delegate of the view controller to be the cell. This seems unnecessary.

It also means that as there is only one view controller, and delegates are a one-to-one communication pattern, your view controller only hides the image on one cell.

To fix this use NotificationCenter in the TopCategoriesCell initialiser as follows:

init(coder aDecoder: NSCoder) {
  super.init(coder: aDecoder)
  NotificationCenter.default.addObserver(self, selector: #selector(TopCategoriesCell.closeTopBar), name: NSNotification.Name(rawValue: "scrolledDown"), object: nil)
  NotificationCenter.default.addObserver(self, selector: #selector(TopCategoriesCell.openTopBar), name: NSNotification.Name(rawValue: "scrolledUp"), object: nil)
}

Note that which init function you place it in depends on how you are instantiating the cell.

Then, in your view controller:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
  if scrollView.contentOffset.y > 160 {
     NotificationCenter.default.post(name: NSNotification.Name(rawValue: "scrolledDown"), object: nil)
  } else {
    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "scrolledUp"), object: nil)
    openAnimation()              
  }
}

And in the TopCategoriesCell:

deinit {
  NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: "scrolledDown"), object: nil)
  NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: "scrolledUp"), object: nil)
}

Upvotes: 1

Related Questions