How to add animation while changing the hidden mode of a uiview?

IosAnimationButtonUiviewNavigationbar

Ios Problem Overview


I want to add animation to a view while changing its hidden mode i.e

my_view.hidden=YES;

I have added a button in navigationbar. When we click on it the new view is set to be unhide. It draws at the upper of the navigation table.

Ios Solutions


Solution 1 - Ios

Animate the view's opacity from 100% to 0%. Have the animation completion callback set the view to be hidden. You might also want to reset the opacity back to 100% during the callback, so the view will display fully opaque when you unhide it.

yourView.alpha = 0.0 //for zero opacity
yourView.alpha = 1.0 //for 100% opacity

Solution 2 - Ios

There is no animation for hiding however; you get the same result with the Swift code below:

UIView.animate(withDuration: 0.2, delay: 0, options: [], animations: {            
    self.yourView.alpha = 0 // Here you can change the alpha property of the view 
}, completion: { _ in  
    self.yourView.isHidden = true // Here you hide it when animation done
})

Solution 3 - Ios

Unfortunately, hidden is not a property that is animatable through UIView animations. I think your best bet may be to use one of the animations @Erik B suggested, or start dabbling with Core Animations which are much more powerful. Take a glance at the documentation for UIView animations and Core Animations.

I achieved something like what your suggesting by using UIView animations to slide the new view from below another view. This made it appear like a drawer sliding out. If you want to do something like that, you need to intercept the touch up inside event and place the animation code there.

- (IBAction)buttonClicked:(id)sender {
    [UIView animateWithDuration:0.5
                          delay:0.0 
                        options:UIViewAnimationCurveEaseOut
                     animations:^(void) {
                        self.myView.frame = /* set the frame here */
                     } 
                     completion:NULL];
}

Solution 4 - Ios

I think more appropriate way to do it is:

[UIView transitionWithView:aView
                  duration:0.3
                   options:UIViewAnimationOptionTransitionCrossDissolve 
                animations:^(void){
                              aView.hidden = NO;
                           }
                completion:nil];

Solution 5 - Ios

Updated to Swift 3:

UIView.animate(withDuration: 0.2, delay: 0.2, options: .curveEaseOut,
      animations: {firstView.alpha = 0}, 
      completion: { _ in firstView.isHidden = true
        //Do anything else that depends on this animation ending
    })

And if you wish to animate something back after first view is gone, you can replicate the code inside the completion block with alpha = 1 and hidden = false.

Solution 6 - Ios

Here's a category I wrote to introduce a new "hidden" property on UIView which correctly supports animation:

@implementation UIView (AnimateHidden)

-(void)setHiddenAnimated:(BOOL)hide
{
  [UIView animateWithDuration:0.5
                        delay:0.0
                      options: UIViewAnimationCurveEaseOut
                   animations:^
                             {
                           [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
                           if (hide)
                             self.alpha=0;
                           else
                           {
                             self.hidden= NO;
                             self.alpha=1;
                           }
                         }
      completion:^(BOOL b)
      {
        if (hide)
          self.hidden= YES;
      }
  ];
}
@end

Solution 7 - Ios

This is corrected N.J. version:

@implementation UIView (AnimateHidden)

-(void)setHiddenAnimated:(BOOL)hide duration:(NSTimeInterval)duration {
    if(self.hidden == hide)
        return;
    if(hide)
        self.alpha = 1;
    else {
        self.alpha = 0;
        self.hidden = NO;
    }
    [UIView animateWithDuration:duration animations:^{
        if (hide)
            self.alpha = 0;
        else
            self.alpha = 1;
    } completion:^(BOOL finished) {
        if(finished)
            self.hidden = hide;
    }];
}

@end

Solution 8 - Ios

Here is swift version for this :

Swift 2

UIView.animateWithDuration(0.5, delay: 0.2, options: UIViewAnimationOptions.CurveEaseOut, animations: {
    objView.alpha = 0
}, completion: { finished in
    objView.hidden = true
})

Swift 3, 4, 5

UIView.animate(withDuration: 0.5, delay: 0.2, options: UIView.AnimationOptions.curveEaseOut, animations: {
    objView.alpha = 0
}, completion: { finished in
    objView.isHidden = true
})

This performs animation with duration of 5 seconds and after delay of 2 seconds.

Available AnimationOptions are :

CurveEaseInOut, CurveEaseIn, CurveEaseOut, CurveLinear

Solution 9 - Ios

Since a few of these answers are a bit cluttered I figured I could post my minimalistic design of this API. I also added the delay and duration - because why not.

In the implementation we have.

#import "UIView+AnimateHidden.h"

@implementation UIView (AnimateHidden)

- (void)setHiddenAnimated:(BOOL)hide
                    delay:(NSTimeInterval)delay
                 duration:(NSTimeInterval)duration {
    [UIView animateWithDuration:duration
                          delay:delay
                        options:UIViewAnimationOptionAllowAnimatedContent
                     animations:^{
                         if (hide) {
                             self.alpha = 0;
                         } else {
                             self.alpha = 0;
                             self.hidden = NO; // We need this to see the animation 0 -> 1
                             self.alpha = 1;
                         }
    } completion:^(BOOL finished) {
        self.hidden = hide;
    }];
}

@end

In the header file we have.

#import <UIKit/UIKit.h>

@interface UIView (AnimateHidden)

- (void)setHiddenAnimated:(BOOL)hide
                    delay:(NSTimeInterval)delay
                 duration:(NSTimeInterval)duration;

@end

Solution 10 - Ios

NJ's and Stanislav's answers here helped me make a new category for this, which I think improves on their answers, so thought I'd post what I came up with in case it helps anyone else.

Note it will only work in iOS4 or later as it's using blocks.

UIView+AnimateHidden.m

#import "UIView+AnimateHidden.h"

@implementation UIView (AnimateHidden)

- (void)setHidden:(BOOL)hidden animated:(BOOL)animated
{
    // If the hidden value is already set, do nothing
    if (hidden == self.hidden) {
        return;
    }
    // If no animation requested, do the normal setHidden method
    else if (animated == NO) {
        [self setHidden:hidden];
        return;
    }
    else {
        // Store the view's current alpha value
        CGFloat origAlpha = self.alpha;
        
        // If we're unhiding the view, make it invisible initially
        if (hidden == NO) {
            self.alpha = 0;
        }
        
        // Unhide the view so we can see the animation
        self.hidden = NO;
        
        // Do the animation
        [UIView animateWithDuration:0.5
                              delay:0.0
                            options: UIViewAnimationOptionCurveEaseOut
                         animations:^{
            // Start animation block
            if (hidden == YES) {
                self.alpha = 0;
            }
            else {
                self.alpha = origAlpha;
            }
            // End animation block
        }
                        completion:^(BOOL b){
            // Start completion block
            // Finish up by hiding the view if necessary...
            self.hidden = hidden;
            // ... and putting back the correct alpha value
            self.alpha = origAlpha;
            // End completion block
        }];
    }
}

@end

Solution 11 - Ios

Another version if you wish to use more complex animation types or animations not supported by the UIView

- (void)setHidden:(BOOL)hidden withAnimationDuration:(NSTimeInterval)duration
{
    CATransition* transition = ({
        CATransition* its = [CATransition animation];
        its.duration = duration;
        its.timingFunction =
            [CAMediaTimingFunction
             functionWithName: kCAMediaTimingFunctionEaseInEaseOut];
        its.type = kCATransitionPush;
        its.subtype = (hidden ? @"fromBottom" : @"fromTop");
        its
    });

    UIView* containerView = self.superview;
    [containerView.layer removeAllAnimations];
    [containerView.layer addAnimation: transition forKey: kCATransition];

    self.hidden = hidden;

    if (!hidden) {
        [self.superview bringSubviewToFront: self];
    }
}

Solution 12 - Ios

Here is the code I used to model a view "growing" and "shrinking" on a "show more..." and "show less ..." button click. Modeled off the answer from Palyancodr

This approach allows me to create both views in the storyboard so that the constraints work as expected on the different iOS devices and I don't need to custom code all the constraints.

@IBAction func showMoreOrLessAction(_ sender: Any) {
    // if small view showing
    if showMoreLargeView.isHidden {
        showMoreSmallView.isHidden = true
        
        //showMoreLargeView.isHidden = false
        UIView.animate(withDuration: 0.2, delay: 0, options: [], animations: {
            self.showMoreLargeView.alpha = 1 // Here you will get the animation you want
        }, completion: { _ in
            self.showMoreLargeView.isHidden = false // Here you hide it when animation done
        })
    }
    else { // large view showing
        //showMoreSmallView.isHidden = false
        UIView.animate(withDuration: 0.2, delay: 0, options: [], animations: {
            self.showMoreSmallView.alpha = 1 // Here you will get the animation you want
        }, completion: { _ in
            self.showMoreSmallView.isHidden = false // Here you hide it when animation done
        })
        
        showMoreLargeView.isHidden = true
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSanchit PaurushView Question on Stackoverflow
Solution 1 - IosJeremy W. ShermanView Answer on Stackoverflow
Solution 2 - IosPalyancodrView Answer on Stackoverflow
Solution 3 - IosEytanView Answer on Stackoverflow
Solution 4 - IosAbhiView Answer on Stackoverflow
Solution 5 - IosPaula HasstenteufelView Answer on Stackoverflow
Solution 6 - IosN.J.View Answer on Stackoverflow
Solution 7 - IosStanView Answer on Stackoverflow
Solution 8 - IosJayprakash DubeyView Answer on Stackoverflow
Solution 9 - IosEntalpiView Answer on Stackoverflow
Solution 10 - IosCraig BrownView Answer on Stackoverflow
Solution 11 - IosHofiView Answer on Stackoverflow
Solution 12 - IosJacksonsoxView Answer on Stackoverflow