Animating UIView isHidden subviews

Viewed 21921

I have a UIView EmptyCollectionView, which I display when my UICollectionView is empty. The way I have this working is that I create the UIView and addSubview in viewDidLoad of my ViewController, then change toggle isHidden property of the view (as well as the collectionview) as needed.

I'd like to polish things up a little now I have the core function working, and I wan't to add some subtle animation to the subviews contained in my empty view, such as making the contained imageview bounce on display.

So my question is, what is the best way to detect when the UIView is being shown (i.e. is there a viewDidAppear type callback I could use)?

Supplementary question: I'm new to this... Is adding the empty view and toggling the isHidden property a good way of doing this? Or should I be doing it a different way? (i.e. should I instead be creating and destroying the view as needed, rather than keeping it around)

Thanks

5 Answers

The best way in my opinion is to extend UIView

extension UIView {

    func fadeIn(_ duration: TimeInterval? = 0.2, onCompletion: (() -> Void)? = nil) {
        self.alpha = 0
        self.isHidden = false
        UIView.animate(withDuration: duration!,
                       animations: { self.alpha = 1 },
                       completion: { (value: Bool) in
                          if let complete = onCompletion { complete() }
                       }
        )
    }

    func fadeOut(_ duration: TimeInterval? = 0.2, onCompletion: (() -> Void)? = nil) {
        UIView.animate(withDuration: duration!,
                       animations: { self.alpha = 0 },
                       completion: { (value: Bool) in
                           self.isHidden = true
                           if let complete = onCompletion { complete() }
                       }
        )
    }

}

So you just have to call view.fadeIn() for a default 0.2 sec animation, or view.fadeIn(1) to make it last one second.

You can even add a completion event:

view.fadeOut(0.5, onCompletion: {
    print("Animation completed, do whatever you want")
})

Swift 4.2 extension to allow animation when setting isHidden on any UIView class:

extension UIView {
    func setIsHidden(_ hidden: Bool, animated: Bool) {
        if animated {
            if self.isHidden && !hidden {
                self.alpha = 0.0
                self.isHidden = false
            }
            UIView.animate(withDuration: 0.25, animations: {
                self.alpha = hidden ? 0.0 : 1.0
            }) { (complete) in
                self.isHidden = hidden
            }
        } else {
            self.isHidden = hidden
        }
    }
}

Swift 5

import UIKit

extension UIView {
    
    func animateSetHidden(_ hidden: Bool, duration: CGFloat = CATransaction.animationDuration(), completion: @escaping (Bool)->() = { _ in}) {
        
        if duration > 0 {

            if self.isHidden && !hidden {
                self.alpha = 0
                self.isHidden = false
            } 
            UIView.animate(withDuration: duration, delay:0, options: .beginFromCurrentState) {
            
                self.alpha = hidden ? 0 : 1
            
            } completion: { c in
          
                if c {
                    self.isHidden = hidden
                }
                completion(c)
            
            }

        } else {
            
            self.isHidden = hidden
            self.alpha = hidden ? 0 : 1
            completion(true)

        }
        
    }

}
Related