1

How to animate collection view cells like a closing or a sliding from the left-right door in iOS. like this: enter image description here

Furkan
  • 306
  • 4
  • 17
Pramod More
  • 1,220
  • 2
  • 22
  • 51
  • 2
    This isn't a question, it looks more like showing off. [It's OK to ask and answer your own question](https://stackoverflow.blog/2011/07/01/its-ok-to-ask-and-answer-your-own-questions/) but make sure it actually is a question. Also take a look at [how to ask and self-answer a question](https://meta.stackoverflow.com/questions/314165/how-to-ask-and-self-answer-a-correct-high-quality-qa-pair-without-attracting-d) – André Kool Mar 30 '18 at 09:29

1 Answers1

11

This is code for animation collection view cells like a closing door. This collection has 2 columns. I have added code for UICollectionViewDelegateFlowLayout methods for collection view cell sizes. You can customize it or change it as per your requirement.

enter image description here

This code shows a simple way to generate animation like a closing door.

    // MARK: - UICollectionViewDelegateFlowLayout
    extension SettingsViewController: UICollectionViewDelegateFlowLayout {

        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
            return CGSize(width:CGFloat(settingsCollectionView.frame.size.width * 0.46), height: settingsCollectionView.frame.size.height * 0.25)
        }

        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
            return 10
        }

        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
            return 10
        }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

            // create a new cell if needed or reuse an old one
            let cell: SettingsCollectionCell = settingsCollectionView.dequeueReusableCell(withReuseIdentifier: identifier, for: indexPath) as! SettingsCollectionCell

            if !cell.isAnimated {

                UIView.animate(withDuration: 0.5, delay: 0.5 * Double(indexPath.row), usingSpringWithDamping: 1, initialSpringVelocity: 0.5, options: indexPath.row % 2 == 0 ? .transitionFlipFromLeft : .transitionFlipFromRight, animations: {

                    if indexPath.row % 2 == 0 {
                        AnimationUtility.viewSlideInFromLeft(toRight: cell)
                    }
                    else {
                        AnimationUtility.viewSlideInFromRight(toLeft: cell)
                    }

                }, completion: { (done) in
                    cell.isAnimated = true
                })
            }

       return cell
    }
}

This is code for AnimationUtility class.

class AnimationUtility: UIViewController, CAAnimationDelegate {

    static let kSlideAnimationDuration: CFTimeInterval = 0.4

    static func viewSlideInFromRight(toLeft views: UIView) {
        var transition: CATransition? = nil
        transition = CATransition.init()
        transition?.duration = kSlideAnimationDuration
        transition?.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        transition?.type = kCATransitionPush
        transition?.subtype = kCATransitionFromRight
//        transition?.delegate = (self as! CAAnimationDelegate)
        views.layer.add(transition!, forKey: nil)
    }

    static func viewSlideInFromLeft(toRight views: UIView) {
        var transition: CATransition? = nil
        transition = CATransition.init()
        transition?.duration = kSlideAnimationDuration
        transition?.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        transition?.type = kCATransitionPush
        transition?.subtype = kCATransitionFromLeft
//        transition?.delegate = (self as! CAAnimationDelegate)
        views.layer.add(transition!, forKey: nil)
    }

    static func viewSlideInFromTop(toBottom views: UIView) {
        var transition: CATransition? = nil
        transition = CATransition.init()
        transition?.duration = kSlideAnimationDuration
        transition?.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        transition?.type = kCATransitionPush
        transition?.subtype = kCATransitionFromBottom
//        transition?.delegate = (self as! CAAnimationDelegate)
        views.layer.add(transition!, forKey: nil)
    }

    static func viewSlideInFromBottom(toTop views: UIView) {
        var transition: CATransition? = nil
        transition = CATransition.init()
        transition?.duration = kSlideAnimationDuration
        transition?.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        transition?.type = kCATransitionPush
        transition?.subtype = kCATransitionFromTop
//        transition?.delegate = (self as! CAAnimationDelegate)
        views.layer.add(transition!, forKey: nil)
    }
}
Pramod More
  • 1,220
  • 2
  • 22
  • 51
  • 1
    This is good code and easy to understand, but I can't find the `cell.isAnimated` property. When I copy and paste your code into my project, I get the error: `Value of type 'CollectionViewCell' has no member 'isAnimated'`. Thoughts? – Phontaine Judd Nov 06 '19 at 18:34
  • 1
    This was variable added in custom cell class. – Pramod More Nov 08 '19 at 12:52
  • This actually works! Don't forget to add var isAnimated = false in your UICollectionViewCell class – mumble57 May 24 '21 at 06:19