Fade In Fade Out Animation

2020-05-11 10:32发布

问题:

Here is some code I struggle with for a while.

If you start the fade in animation, the label text fades in. If I start the fade out animation the the label text fades out.

When I start the startFade method, only fade out is shown. How can I wait for the fadeIn method to finish visually before starting the fadeOut method.

-(IBAction)startFade:(id)sender{
    [self fadeIn];
    [self fadeOut];
}

-(IBAction)fadeIn:(id)sender{
    [self fadeIn];
}

-(IBAction)fadeOut:(id)sender{
[self fadeOut];
}

-(void) fadeIn{
    [_label setAlpha:0];
    [UILabel beginAnimations:NULL context:nil];
    [UILabel setAnimationDuration:2.0];
    [_label setAlpha:1];
    [UILabel commitAnimations];
}

-(void) fadeOut{
    [UILabel beginAnimations:NULL context:nil];
    [UILabel setAnimationDuration:2.0];
    [_label setAlpha:0];
    [UILabel commitAnimations];
}

回答1:

When you call the fadeIn and fadeOut methods back to back like you're doing, the code is run instantaneously, so you'll only see animation from the last method called. UIView block based animation provides a completion handler, which seems to be exactly what you're looking for. So your code might looks something like this:

-(IBAction)startFade:(id)sender {

    [_label setAlpha:0.0f];        

    //fade in
    [UIView animateWithDuration:2.0f animations:^{

        [_label setAlpha:1.0f];

    } completion:^(BOOL finished) {

        //fade out
        [UIView animateWithDuration:2.0f animations:^{

            [_label setAlpha:0.0f];

        } completion:nil];

    }];
}

Swift:

@IBAction func startFade(_ sender: AnyObject) {

    label.alpha = 0.0

    // fade in
    UIView.animate(withDuration: 2.0, animations: { 
        label.alpha = 1.0
    }) { (finished) in
        // fade out
        UIView.animate(withDuration: 2.0, animations: {
            label.alpha = 0.0
        })
    }
}


回答2:

that does the job for you (the _label is your label);

- (IBAction)startFade:(id)sender {
    [_label setAlpha:0.f];

    [UIView animateWithDuration:2.f delay:0.f options:UIViewAnimationOptionCurveEaseIn animations:^{
        [_label setAlpha:1.f];
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:2.f delay:0.f options:UIViewAnimationOptionCurveEaseInOut animations:^{
            [_label setAlpha:0.f];
        } completion:nil];
    }];
}


回答3:

Try this..

// Fade Out

 -(void)fadeOut:(UIView*)viewToDissolve withDuration:(NSTimeInterval)duration   andWait:(NSTimeInterval)wait
{
[UIView beginAnimations: @"Fade Out" context:nil];

// wait for time before begin
[UIView setAnimationDelay:wait];

// druation of animation
[UIView setAnimationDuration:duration];
viewToDissolve.alpha = 0.0;
[UIView commitAnimations];
}

// Fade In

-(void) fadeIn:(UIView*)viewToFadeIn withDuration:(NSTimeInterval)duration andWait:(NSTimeInterval)wait

{
[UIView beginAnimations: @"Fade In" context:nil];

// wait for time before begin
[UIView setAnimationDelay:wait];

    // druation of animation
[UIView setAnimationDuration:duration];
viewToFadeIn.alpha = 1;
[UIView commitAnimations];

}

// Fade in from fade out

-(void) fadeInFromFadeOut: (UIView*)viewToFadeIn withDuration:(NSTimeInterval)duration
{
    viewToFadeIn.hidden=NO;
    [self fadeOut:viewToFadeIn withDuration:1 andWait:0];
    [self fadeIn:viewToFadeIn withDuration:duration andWait:0];

}

// Button operation

-(void) buttonClicked :(id)sender
{
   NSLog(@"Button clicked");

// Each button is given a tag
int tag = ((UIButton*)sender).tag;
if (tag ==1)
{
    sprite.alpha  =1;
    [self fadeOut : sprite withDuration: 10 andWait : 1 ];
}
else if (tag ==2)
{
    sprite.alpha  =0;
    [self fadeIn : sprite withDuration: 3 andWait : 1 ];
}
else
{
    [self fadeInFromFadeOut:sprite withDuration:10];
}
}

View this link to download sample..

Refer this link.

Happy to share with you..:-)



回答4:

Generic answer : You can use this method to apply animation to any UIView object . First create an extension of UIView class . Create a separate swift file and write the code like this

import Foundation
import UIKit

extension UIView {

    func fadeIn() {
        //Swift 2
        UIView.animateWithDuration(1.0, delay: 0.0, options: UIViewAnimationOptions.CurveEaseIn, animations: {
            self.alpha = 1.0
        }, completion: nil)

        //Swift 3, 4, 5
        UIView.animate(withDuration: 1.0, delay: 0.0, options: UIView.AnimationOptions.curveEaseIn, animations: {
            self.alpha = 1.0
        }, completion: nil)
    }


    func fadeOut() {
        //Swift 2
        UIView.animateWithDuration(1.0, delay: 0.0, options: UIViewAnimationOptions.CurveEaseOut, animations: {
            self.alpha = 0.0
        }, completion: nil)

        //Swift 3, 4, 5
        UIView.animate(withDuration: 1.0, delay: 0.0, options: UIView.AnimationOptions.curveEaseOut, animations: {
            self.alpha = 0.0
        }, completion: nil)
    }


}

Here self refers to any UIView you refer to . You can use buttons, labels etc to call these 2 methods .

Then in any other swift class you can call fadeIn() and fadeOut() like this :

self.yourUIObject.fadeIn()
self.yourUIObject.fadeOut()

This gives the desired effect of animation to any UIObject .



回答5:

you can do something like this (check possible parameters values and similar methods here : https://developer.apple.com/library/ios/documentation/uikit/reference/uiview_class/uiview/uiview.html

[UIView animateWithDuration:duration
                      delay:delay
                    options:option 
                 animations:^{
                     //fade in here (changing alpha of UILabel component)
                 } 
                 completion:^(BOOL finished){
                    if(finished){
                      //start a fade out here when previous animation is finished (changing alpha of UILabel component)
                 }];
}


回答6:

Based on @holex's answer, but simplified a bit (as commented):

- (IBAction)startFade:(id)sender {
   [_label setAlpha:0.f];

   [UIView animateWithDuration:2.f 
                         delay:0.f 
                       options:UIViewAnimationOptionCurveEaseIn
                             | UIViewAnimationOptionAutoreverse 
                    animations:^{
                                  [_label setAlpha:1.f];
                                } 
                    completion:nil];
}


回答7:

The easiest way would be to use:

[UIView animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion]

and add the fadeOut call to the completion block. The documentation might help answer any questions you have.

If you can't use the block version for some reason, then you'll have to set a delegate ([UIView setAnimationDelegate:(id)delegate]) and a selector with ([UIView setAnimationDidStopSelector:]) that the delegate will respond to.

Again, see the documentation for more details.



回答8:

My task was to make a label fade out. And then fade in with changed text. The solution was:

    -(void)performAnimationOnHistoryButtonLabelUpdatingTextTo:(NSString *)text
{
    [UIView animateWithDuration:0.4f animations:^{
        [self.historyButtonLabel setAlpha:0.0f];

    } completion:^(BOOL finished) {
        self.historyButtonLabel.text = text;

        [UIView animateWithDuration:0.4f animations:^{
            [self.historyButtonLabel setAlpha:1.0f];
        } completion:nil];

    }];
}


回答9:

labelAnimate = (UILabel*) [self.view viewWithTag:101];
btnTapMe = (UIButton*) [self.view viewWithTag:100];
[btnTapMe addTarget:self action:@selector(startAnimating:) forControlEvents:UIControlEventTouchUpInside];

//////////////

-(void) startAnimating:(UIButton*)button {
    [labelAnimate setAlpha:0.0];
    [NSTimer scheduledTimerWithTimeInterval:1.8 target:self selector:@selector(continuousEaseInOut) userInfo:button repeats:YES];
}

-(void) continuousFadeInOut {
    [UIView animateWithDuration:2.0 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
        [labelAnimate setAlpha:1.0];
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:2.0 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
            [labelAnimate setAlpha:0.0];
        } completion:nil];
    }];
}


回答10:

I strongly suggest you use a generic implementation so you can reuse the code whenever you need the fade effect again.

You should create an UIView extension:

UIView+Animations.h

#import <Foundation/Foundation.h>

@interface UIView (Animations)

- (void)fadeInWithCompletion:(void (^ __nullable)(BOOL finished))completion;
- (void)fadeOutWithCompletion:(void (^ __nullable)(BOOL finished))completion;;

@end

UIView+Animations.m

#import "UIView+Animations.h"

@implementation UIView (Animations)

- (void)fadeInWithCompletion:(void (^ __nullable)(BOOL finished))completion {
    [UIView animateWithDuration:2 animations:^{
        [self setAlpha:1];
    } completion:completion];
}

- (void)fadeOutWithCompletion:(void (^ __nullable)(BOOL finished))completion {
    [UIView animateWithDuration:2 animations:^{
        [self setAlpha:0];
    } completion:completion];
}

@end

So, you only have to import the new file to your class or inside your Prefix.pch and use it like this:

[_label fadeOutWithCompletion:^(BOOL finished) {
   [_label fadeInWithCompletion:nil];
}];

Note that you could also use nil as the completion parameter when you have nothing else to do after completion.

I also recommend you do not parameterize the duration to keep a pattern through you entire application.

This implementation can be used in the future for UIButton, UILabel, UITextField... Well, any class derived from UIView.



回答11:

Swift 4 If you need just one pulse when clicking the button, use that:

@IBAction func didPressButton(_ sender: UIButton) {
        self.someView.alpha = 0
        UIView.animate(withDuration: 0.4,
                       delay: 0,
                       options: [.curveEaseInOut, .autoreverse],
                       animations: {
                        self.someView.alpha = 1
        },
                       completion: { _ in
                        self.someView.alpha = 0
        })
    }


回答12:

The fade in and fade out animations can be combined using UIView.animate(withDuration: animations:)

UIView.animate(withDuration: animationDuration, animations: {
            myView.alpha = 0.75
            myView.alpha = 1.0
        })


回答13:

Swift 5 version of iPhoneDeveloper's answer:

extension UIView {

func fadeIn() {
    UIView.animate(withDuration: 1.0, delay: 0.0, options: UIView.AnimationOptions.curveEaseIn, animations: {
        self.alpha = 1.0
    }, completion: nil)
}


func fadeOut() {
    UIView.animate(withDuration: 1.0, delay: 0.0, options: UIView.AnimationOptions.curveEaseOut, animations: {
        self.alpha = 0.0
    }, completion: nil)
}

}