My simple goal is to fade animate hiding and showing functions.
Button.hidden = YES;
Simple enough. However, is it possible to have it fade out rather than just disappearing? It looks rather unprofessional that way.
My simple goal is to fade animate hiding and showing functions.
Button.hidden = YES;
Simple enough. However, is it possible to have it fade out rather than just disappearing? It looks rather unprofessional that way.
 
    
     
    
    In iOS 4 and later, there's a way to do this just using the UIView transition method without needing to import QuartzCore. You can just say:
[UIView transitionWithView:button
                  duration:0.4
                   options:UIViewAnimationOptionTransitionCrossDissolve
                animations:^{
                     button.hidden = YES;
                }
                completion:NULL];
UIView.transition(with: button, duration: 0.4, 
                  options: .transitionCrossDissolve, 
                  animations: {
                 self.button.isHidden = false
              })
Michail's solution will work, but it's not actually the best approach.
The problem with alpha fading is that sometimes the different overlapping view layers look weird as they fade out. There are some other alternatives using Core Animation. First include the QuartzCore framework in your app and add #import <QuartzCore/QuartzCore.h> to your header. Now you can do one of the following:
button.layer.shouldRasterize = YES; and then use the alpha animation code that Michail provided in his answer. This will prevent the layers from blending weirdly, but has a slight performance penalty, and can make the button look blurry if it's not aligned exactly on a pixel boundary.Alternatively:
Use the following code to animate the fade instead:
CATransition *animation = [CATransition animation]; animation.type = kCATransitionFade; animation.duration = 0.4; [button.layer addAnimation:animation forKey:nil];
button.hidden = YES;
The nice thing about this approach is you can crossfade any property of the button even if they aren't animatable (e.g. the text or image of the button), just set up the transition and then set your properties immediately afterwards.
 
    
     
    
    UIView animated properties are:
- frame
- bounds
- center
- transform
- alpha
- backgroundColor
- contentStretch
Describe in: Animations
isHidden is not one of them, so as I see it the best way is:
Swift 4:
func setView(view: UIView, hidden: Bool) {
    UIView.transition(with: view, duration: 0.5, options: .transitionCrossDissolve, animations: {
        view.isHidden = hidden
    })
}
Objective C:
- (void)setView:(UIView*)view hidden:(BOOL)hidden {
    [UIView transitionWithView:view duration:0.5 options:UIViewAnimationOptionTransitionCrossDissolve animations:^(void){
        [view setHidden:hidden];
    } completion:nil];
}
To fade out:
Objective-C
[UIView animateWithDuration:0.3 animations:^{
    button.alpha = 0;
} completion: ^(BOOL finished) {//creates a variable (BOOL) called "finished" that is set to *YES* when animation IS completed.
    button.hidden = finished;//if animation is finished ("finished" == *YES*), then hidden = "finished" ... (aka hidden = *YES*)
}];
Swift 2
UIView.animateWithDuration(0.3, animations: {
    button.alpha = 0
}) { (finished) in
    button.hidden = finished
}
Swift 3, 4, 5
UIView.animate(withDuration: 0.3, animations: {
    button.alpha = 0
}) { (finished) in
    button.isHidden = finished
}
To fade in:
Objective-C
button.alpha = 0;
button.hidden = NO;
[UIView animateWithDuration:0.3 animations:^{
    button.alpha = 1;
}];
Swift 2
button.alpha = 0
button.hidden = false
UIView.animateWithDuration(0.3) {
    button.alpha = 1
}
Swift 3, 4, 5
button.alpha = 0
button.isHidden = false
UIView.animate(withDuration: 0.3) {
    button.alpha = 1
}
 
    
     
    
    Use this solution for a smooth fadeOut and fadeIn effects
extension UIView {
    func fadeIn(duration: TimeInterval = 0.5, delay: TimeInterval = 0.0, completion: @escaping ((Bool) -> Void) = {(finished: Bool) -> Void in }) {
        self.alpha = 0.0
        UIView.animate(withDuration: duration, delay: delay, options: UIView.AnimationOptions.curveEaseIn, animations: {
            self.isHidden = false
            self.alpha = 1.0
        }, completion: completion)
    }
    func fadeOut(duration: TimeInterval = 0.5, delay: TimeInterval = 0.0, completion: @escaping (Bool) -> Void = {(finished: Bool) -> Void in }) {
        self.alpha = 1.0
        UIView.animate(withDuration: duration, delay: delay, options: UIView.AnimationOptions.curveEaseOut, animations: {
            self.isHidden = true
            self.alpha = 0.0
        }, completion: completion)
    }
}
usage is as like
uielement.fadeIn()
uielement.fadeOut()
Thanks
 
    
    I use this little Swift 3 extension:
extension UIView {
  func fadeIn(duration: TimeInterval = 0.5,
              delay: TimeInterval = 0.0,
              completion: @escaping ((Bool) -> Void) = {(finished: Bool) -> Void in }) {
    UIView.animate(withDuration: duration,
                   delay: delay,
                   options: UIViewAnimationOptions.curveEaseIn,
                   animations: {
      self.alpha = 1.0
    }, completion: completion)
  }
  func fadeOut(duration: TimeInterval = 0.5,
               delay: TimeInterval = 0.0,
               completion: @escaping (Bool) -> Void = {(finished: Bool) -> Void in }) {
    UIView.animate(withDuration: duration,
                   delay: delay,
                   options: UIViewAnimationOptions.curveEaseIn,
                   animations: {
      self.alpha = 0.0
    }, completion: completion)
  }
}
 
    
    Swift 3
func appearView() {
     self.myView.alpha = 0
     self.myView.isHidden = false
     UIView.animate(withDuration: 0.9, animations: {
         self.myView.alpha = 1
     }, completion: {
         finished in
         self.myView.isHidden = false
     })
}
 
    
    swift 4.2
with extension :
extension UIView {
func hideWithAnimation(hidden: Bool) {
        UIView.transition(with: self, duration: 0.5, options: .transitionCrossDissolve, animations: {
            self.isHidden = hidden
        })
    }
}
simple method:
func setView(view: UIView, hidden: Bool) {
    UIView.transition(with: view, duration: 0.5, options: .transitionCrossDissolve, animations: {
        view.isHidden = hidden
    })
}
 
    
    the code of @Umair Afzal working fine in swift 5 after some changes
 extension UIView {
func fadeIn(duration: TimeInterval = 0.5, delay: TimeInterval = 0.0, completion: @escaping ((Bool) -> Void) = {(finished: Bool) -> Void in }) {
    self.alpha = 0.0
    UIView.animate(withDuration: duration, delay: delay, options: UIView.AnimationOptions.curveEaseIn, animations: {
        self.isHidden = false
        self.alpha = 1.0
    }, completion: completion)
}
func fadeOut(duration: TimeInterval = 0.5, delay: TimeInterval = 0.0, completion: @escaping (Bool) -> Void = {(finished: Bool) -> Void in }) {
    self.alpha = 1.0
    UIView.animate(withDuration: duration, delay: delay, options: UIView.AnimationOptions.curveEaseIn, animations: {
        self.alpha = 0.0
    }) { (completed) in
        self.isHidden = true
        completion(true)
    }
  }
}
for use
yourView.fadeOut()
yourView.fadeIn()
 
    
    I created category for UIView for this purpose and implemented a special little bit different concept: visibility. The main difference of my solution is that you can call [view setVisible:NO animated:YES] and right after that synchronously check [view visible] and get correct result. This is pretty simple but extremely useful.
Besides, it is allowed to avoid using "negative boolean logic" (see Code Complete, page 269, Use positive boolean variable names for more information).
UIView+Visibility.swift
import UIKit
private let UIViewVisibilityShowAnimationKey = "UIViewVisibilityShowAnimationKey"
private let UIViewVisibilityHideAnimationKey = "UIViewVisibilityHideAnimationKey"
private class UIViewAnimationDelegate: NSObject {
    weak var view: UIView?
    dynamic override func animationDidStop(animation: CAAnimation, finished: Bool) {
        guard let view = self.view where finished else {
            return
        }
        view.hidden = !view.visible
        view.removeVisibilityAnimations()
    }
}
extension UIView {
    private func removeVisibilityAnimations() {
        self.layer.removeAnimationForKey(UIViewVisibilityShowAnimationKey)
        self.layer.removeAnimationForKey(UIViewVisibilityHideAnimationKey)
    }
    var visible: Bool {
        get {
            return !self.hidden && self.layer.animationForKey(UIViewVisibilityHideAnimationKey) == nil
        }
        set {
            let visible = newValue
            guard self.visible != visible else {
                return
            }
            let animated = UIView.areAnimationsEnabled()
            self.removeVisibilityAnimations()
            guard animated else {
                self.hidden = !visible
                return
            }
            self.hidden = false
            let delegate = UIViewAnimationDelegate()
            delegate.view = self
            let animation = CABasicAnimation(keyPath: "opacity")
            animation.fromValue = visible ? 0.0 : 1.0
            animation.toValue = visible ? 1.0 : 0.0
            animation.fillMode = kCAFillModeForwards
            animation.removedOnCompletion = false
            animation.delegate = delegate
            self.layer.addAnimation(animation, forKey: visible ? UIViewVisibilityShowAnimationKey : UIViewVisibilityHideAnimationKey)
        }
    }
    func setVisible(visible: Bool, animated: Bool) {
        let wereAnimationsEnabled = UIView.areAnimationsEnabled()
        if wereAnimationsEnabled != animated {
            UIView.setAnimationsEnabled(animated)
            defer { UIView.setAnimationsEnabled(!animated) }
        }
        self.visible = visible
    }
}
UIView+Visibility.h
#import <UIKit/UIKit.h>
@interface UIView (Visibility)
- (BOOL)visible;
- (void)setVisible:(BOOL)visible;
- (void)setVisible:(BOOL)visible animated:(BOOL)animated;
@end
UIView+Visibility.m
#import "UIView+Visibility.h"
NSString *const UIViewVisibilityAnimationKeyShow = @"UIViewVisibilityAnimationKeyShow";
NSString *const UIViewVisibilityAnimationKeyHide = @"UIViewVisibilityAnimationKeyHide";
@implementation UIView (Visibility)
- (BOOL)visible
{
    if (self.hidden || [self.layer animationForKey:UIViewVisibilityAnimationKeyHide]) {
        return NO;
    }
    return YES;
}
- (void)setVisible:(BOOL)visible
{
    [self setVisible:visible animated:NO];
}
- (void)setVisible:(BOOL)visible animated:(BOOL)animated
{
    if (self.visible == visible) {
        return;
    }
    [self.layer removeAnimationForKey:UIViewVisibilityAnimationKeyShow];
    [self.layer removeAnimationForKey:UIViewVisibilityAnimationKeyHide];
    if (!animated) {
        self.alpha = 1.f;
        self.hidden = !visible;
        return;
    }
    self.hidden = NO;
    CGFloat fromAlpha = visible ? 0.f : 1.f;
    CGFloat toAlpha = visible ? 1.f : 0.f;
    NSString *animationKey = visible ? UIViewVisibilityAnimationKeyShow : UIViewVisibilityAnimationKeyHide;
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
    animation.duration = 0.25;
    animation.fromValue = @(fromAlpha);
    animation.toValue = @(toAlpha);
    animation.delegate = self;
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;
    [self.layer addAnimation:animation forKey:animationKey];
}
#pragma mark - CAAnimationDelegate
- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)finished
{
    if ([[self.layer animationForKey:UIViewVisibilityAnimationKeyHide] isEqual:animation]) {
        self.hidden = YES;
    }
}
@end
 
    
    Swift 5.0, with generics:
func hideViewWithAnimation<T: UIView>(shouldHidden: Bool, objView: T) {
    if shouldHidden == true {
        UIView.animate(withDuration: 0.3, animations: {
            objView.alpha = 0
        }) { (finished) in
            objView.isHidden = shouldHidden
        }
    } else {
        objView.alpha = 0
        objView.isHidden = shouldHidden
        UIView.animate(withDuration: 0.3) {
            objView.alpha = 1
        }
    }
}   
Use:
hideViewWithAnimation(shouldHidden: shouldHidden, objView: itemCountLabelBGView)
hideViewWithAnimation(shouldHidden: shouldHidden, objView: itemCountLabel)
hideViewWithAnimation(shouldHidden: shouldHidden, objView: itemCountButton)
Here itemCountLabelBGView is a UIView, itemCountLabel is a UILabel & itemCountButton is a UIButton, So it will work for every view object whose parent class is UIView.
 
    
    Swift 4
extension UIView {
func fadeIn(duration: TimeInterval = 0.5, delay: TimeInterval = 0.0, completion: @escaping ((Bool) -> Void) = {(finished: Bool) -> Void in }) {
    self.alpha = 0.0
    UIView.animate(withDuration: duration, delay: delay, options: UIViewAnimationOptions.curveEaseIn, animations: {
        self.isHidden = false
        self.alpha = 1.0
    }, completion: completion)
}
func fadeOut(duration: TimeInterval = 0.5, delay: TimeInterval = 0.0, completion: @escaping (Bool) -> Void = {(finished: Bool) -> Void in }) {
    self.alpha = 1.0
    UIView.animate(withDuration: duration, delay: delay, options: UIViewAnimationOptions.curveEaseIn, animations: {
        self.alpha = 0.0
    }) { (completed) in
        self.isHidden = true
        completion(true)
    }
}
}
And to use use it, simple call these functions like:
yourView.fadeOut() // this will hide your view with animation
yourView.fadeIn() /// this will show your view with animation
 
    
    isHidden is an immediate value and you cannot affect an animation on it, instead of this you can use Alpha for hide your view 
UIView.transition(with: view, duration: 0.5, options: .transitionCrossDissolve, animations: {
        view.alpha = 0
    })
And for showing:
UIView.transition(with: view, duration: 0.5, options: .transitionCrossDissolve, animations: {
      view.alpha = 1
})
 
    
    func flipViews(fromView: UIView, toView: UIView) {
    toView.frame.origin.y = 0
    self.view.isUserInteractionEnabled = false
    UIView.transition(from: fromView, to: toView, duration: 0.5, options: .transitionFlipFromLeft, completion: { finished in            
        fromView.frame.origin.y = -900
        self.view.isUserInteractionEnabled = true
    })
}
 
    
    You can try this.
 func showView(objView:UIView){
    objView.alpha = 0.0
    UIView.animate(withDuration: 0.5, animations: {
        objView.alpha = 0.0
    }, completion: { (completeFadein: Bool) -> Void in
        objView.alpha = 1.0
        let transition = CATransition()
        transition.duration = 0.5
        transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        transition.type = kCATransitionFade
        objView.layer.add(transition, forKey: nil)
    })
}
func HideView(objView:UIView){
    UIView.animate(withDuration: 0.5, animations: {
        objView.alpha = 1.0
    }, completion: { (completeFadein: Bool) -> Void in
        objView.alpha = 0.0
        let transition = CATransition()
        transition.duration = 0.5
        transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        transition.type = kCATransitionFade
        objView.layer.add(transition, forKey: nil)
    })
}
And pass your view name
        showView(objView: self.viewSaveCard)
        HideView(objView: self.viewSaveCard)
 
    
    If your view is set to hidden by default or you change the Hidden state which I think you should in many cases, then none of the approaches in this page will give you both FadeIn/FadeOut animation, it will only animate one of these states, the reason is you are setting the Hidden state to false before calling UIView.animate method which will cause a sudden visibility and if you only animate the alpha then the object space is still there but it's not visible which will result to some UI issues.
So the best approach is to check first if the view is hidden then set the alpha to 0.0, like this when you set the Hidden state to false you won't see a sudden visibility.
func hideViewWithFade(_ view: UIView) {
    if view.isHidden {
        view.alpha = 0.0
    }
    view.isHidden = false
    UIView.animate(withDuration: 0.3, delay: 0.0, options: .transitionCrossDissolve, animations: {
        view.alpha = view.alpha == 1.0 ? 0.0 : 1.0
    }, completion: { _ in
        view.isHidden = !Bool(truncating: view.alpha as NSNumber)
    })
}
 
    
    UIView.transition(with:) function is nice and neat.
Many have posted it but none has noticed there lies a fault will show up only when you run it.
You can transition hidden property to true perfectly, whereas when you attempt to transition it to false, the view will simple disappear suddenly without any animation.
That's because this api only works within a view, which means when you transition a view to show, in fact itself shows immediately, only its content animated out gradually.
When you try to hide this view, itself hide right away, makes the animation to its content meaningless.
To solve this, when hiding a view, the transition target should be its parent view instead of the view you want to hide.
func transitionView(_ view: UIView?, show: Bool, completion: BoolFunc? = nil) {
    guard let view = view, view.isHidden == show, let parent = view.superview else { return }
    let target: UIView = show ? view : parent
    UIView.transition(with: target, duration: 0.4, options: [.transitionCrossDissolve], animations: {
        view.isHidden = !show
    }, completion: completion)
}
 
    
    UIView.transition(with: title3Label, duration: 0.4,
                          options: .transitionCrossDissolve,
                          animations: {
                            self.title3Label.isHidden = !self.title3Label.isHidden
                      })
Applying transition on View with some delay gives hide and show effect
 
    
    You can do it VERY easily using Animatics library:
//To hide button:
AlphaAnimator(0) ~> button
//to show button
AlphaAnimator(1) ~> button
 
    
    My solution for Swift 3. So, I created the function, that hide/unhide view in the right order(when hiding - set alpha to 0 and then isHidden to true; unhiding - first reveal the view and then set it's alpha to 1):
func hide(_ hide: Bool) {
    let animations = hide ? { self.alpha = 0 } :
                            { self.isHidden = false }
    let completion: (Bool) -> Void = hide ? { _ in self.isHidden = true } :
                                            { _ in UIView.animate(withDuration: duration, animations: { self.alpha = 1 }) }
    UIView.animate(withDuration: duration, animations: animations, completion: completion)
}
 
    
    Swift 4 Transition
    UIView.transition(with: view, duration: 3, options: .transitionCurlDown,
                      animations: {
                        // Animations
                        view.isHidden = hidden
    },
                      completion: { finished in
                        // Compeleted
    })
If you use the approach for older swift versions you'll get an error :
Cannot convert value of type '(_) -> ()' to expected argument type '(() -> Void)?'
Useful reference.
 
    
    This code give an animation like pushing viewController in uinavigation controller...
CATransition *animation = [CATransition animation];
 animation.type = kCATransitionPush;
 animation.subtype = kCATransitionFromRight;
 animation.duration = 0.3;
 [_viewAccountName.layer addAnimation:animation forKey:nil];
 _viewAccountName.hidden = true;
Used this for pop animation...
 CATransition *animation = [CATransition animation];
 animation.type = kCATransitionPush;
 animation.subtype = kCATransitionFromLeft;
 animation.duration = 0.3;
 [_viewAccountName.layer addAnimation:animation forKey:nil];
 _viewAccountName.hidden = false;
 
    
    Tried some of the exited answers, some only work for one situation, some of them need to add two functions.
Option 1
Nothing to do with view.isHidden.
extension UIView {
    func animate(fadeIn: Bool, withDuration: TimeInterval = 1.0) {
        UIView.animate(withDuration: withDuration, delay: 0.0, options: .curveEaseInOut, animations: {
            self.alpha = fadeIn ? 1.0 : 0.0
        })
    }
}
Then pass isFadeIn (true or false)
view.animate(fadeIn: isFadeIn) 
Option 2
Don't pass any parameter. It fades in or out according to isUserInteractionEnabled. This also suits the situation animate back and forth very well.
func animateFadeInOut(withDuration: TimeInterval = 1.0) {
    self.isUserInteractionEnabled = !self.isUserInteractionEnabled
    UIView.animate(withDuration: withDuration, delay: 0.0, options: .curveEaseInOut, animations: {
        self.alpha = self.isUserInteractionEnabled ? 1.0 : 0.0
    })
}
Then you call
yourView.animateFadeInOut()
Why
self.isUserInteractionEnabled?Tried to replace
self.isUserInteractionEnabledbyself.isHidden, no luck at all.
That's it. Cost me sometime, hope it helps someone.
