淡入淡出动画

63

以下是我苦思冥想了一段时间的代码。

如果您开始淡入动画,标签文本将淡入。 如果我开始淡出动画,标签文本将淡出。

当我启动startFade方法时,只显示淡出效果。 如何等待fadeIn方法在视觉上完成后再开始fadeOut方法。

-(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];
}

你尝试过基于块的动画吗? - holex
13个回答

124

当您像所做的那样连续调用fadeInfadeOut方法时,代码会立即运行,因此您只会看到从最后一个调用的方法开始的动画。UIView基于块的动画提供了完成处理程序,这似乎正是您正在寻找的。因此,您的代码可能看起来像这样:

-(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
        })
    }
}

淡入淡出效果的第二部分在哪里? - holex
我总是忘记做那件事。谢谢你发现了它。 - hgwhittle

34

它可以为您完成工作(_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];
    }];
}

5
可以通过在第一个动画选项中添加UIViewAnimationOptionAutoReverse来简化,即UIViewAnimationOptionCurveEaseIn | UIViewAnimationOptionAutoReverse,并仅使用completion:nil而不是另一个动画。 - Bjørn Egil
@BjørnEgil,如果没有关于在半路更改UILabel的任何属性的目标,那也可以。 - holex
是的,但那不是问题的一部分。问题只是如何淡入淡出。 - Bjørn Egil
1
@BjørnEgil,这个答案试图尽可能地通用,以便其他用户或开发人员可以尝试重复使用这个想法。 - holex

7

通用回答:您可以使用此方法将动画应用于任何UIView对象。 首先创建UIView类的扩展。创建一个单独的Swift文件并编写以下代码:

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)
    }


}

这里的self指代你所引用的任何UIView。你可以使用按钮、标签等来调用这两种方法。

然后在任何其他Swift类中,你可以像这样调用fadeIn()和fadeOut():

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

这将为任何UIObject提供所需的动画效果。


6
尝试这个...
// 渐隐
 -(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];
}

//淡入

-(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];

}

// 淡入淡出

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

}

// 按钮操作

-(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];
}
}

请查看此链接以下载示例。

请参考此链接

很高兴与您分享..:-)


酷炫的东西!大家好啊!我看了很多你们的想法和方法,对我帮助很大! - SoTm

2

Swift 4 如果您只需要在单击按钮时脉冲一次,请使用以下内容:

@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
        })
    }

2

基于@holex的答案,但稍微简化了一下(如评论所述):

- (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];
}

2

2

iPhoneDeveloper的最初回答的Swift 5版本:

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)
    }
}

1
我强烈建议您使用通用实现,这样您就可以在需要再次使用淡入淡出效果的时候重复使用代码。
您应该创建一个UIView扩展:

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

所以,您只需要将新文件导入到您的类中或在Prefix.pch内部,并像这样使用它:
[_label fadeOutWithCompletion:^(BOOL finished) {   [_label fadeInWithCompletion:nil];
}];

请注意,当您在完成后没有其他事情要做时,也可以使用nil作为完成参数。
我还建议您不要将持续时间参数化,以保持整个应用程序的模式。
该实现可用于将来的UIButtonUILabelUITextField等任何派生自UIView类的控件。

1
淡入淡出动画可以使用 UIView.animate(withDuration: animations:) 进行组合。
UIView.animate(withDuration: animationDuration, animations: {
            myView.alpha = 0.75
            myView.alpha = 1.0
        })

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接