Fade In Fade Out Анимация

Вот код, с которым я борюсь некоторое время.

Если вы запускаете плавную анимацию, текст метки постепенно исчезает. Если я запускаю плавную анимацию, текст метки исчезает.

Когда я запускаю метод 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];
}

person HiDuEi    schedule 02.01.2014    source источник
comment
Вы уже пробовали блочную анимацию?   -  person holex    schedule 03.01.2014


Ответы (12)


Когда вы вызываете методы fadeIn и fadeOut последовательно, как вы это делаете, код запускается мгновенно, поэтому вы увидите только анимацию из последнего вызванного метода. Анимация на основе блоков 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];

    }];
}

Быстрый:

@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
        })
    }
}
person hgwhittle    schedule 02.01.2014
comment
... а где вторая половина эффекта затухания? - person holex; 03.01.2014
comment
Я всегда забываю это делать. Спасибо, что поймали это. - person hgwhittle; 03.01.2014

который выполняет эту работу за вас (_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];
    }];
}
person holex    schedule 02.01.2014
comment
Можно упростить, добавив UIViewAnimationOptionAutoReverse к параметрам первой анимации, т.е. UIViewAnimationOptionCurveEaseIn | UIViewAnimationOptionAutoReverse и просто завершение: nil вместо другой анимации. - person Bjørn Egil; 22.05.2014
comment
@ BjørnEgil, если нет такой цели, которая заключается в изменении любого атрибута UILabel между полпути, это также может сработать. - person holex; 23.05.2014
comment
да, но это не было частью вопроса. Это было то, как постепенно появляться и исчезать. - person Bjørn Egil; 23.05.2014
comment
@ BjørnEgil, ответ должен быть как можно более общим для других пользователей или разработчиков, которые могут попытаться повторно использовать эту идею. - person holex; 23.05.2014

Попробуй это..

// Исчезать

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

Просмотрите эту ссылку, чтобы загрузить образец ..

Перейдите по этой ссылке.

Рад поделиться с вами .. :-)

person yazh    schedule 14.08.2014
comment
Прикольные вещи; Всем !! Проверил множество ваших идей и подходов. Мне очень помогло !! - person HiDuEi; 25.08.2014

Общий ответ: вы можете использовать этот метод для применения анимации к любому объекту UIView. Сначала создайте расширение класса UIView. Создайте отдельный быстрый файл и напишите такой код

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, на который вы ссылаетесь. Вы можете использовать кнопки, метки и т. Д. Для вызова этих двух методов.

Затем в любом другом быстром классе вы можете вызвать fadeIn () и fadeOut () следующим образом:

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

Это дает желаемый эффект анимации любому UIObject.

person iPhoneDeveloper    schedule 13.06.2016

вы можете сделать что-то подобное (проверьте возможные значения параметров и аналогичные методы здесь: 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)
                 }];
}
person Julian    schedule 02.01.2014

На основе ответа @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];
}
person Bjørn Egil    schedule 22.05.2014

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
        })
    }
person Nik Kov    schedule 22.07.2018

Самый простой способ - использовать:

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

и добавьте вызов fadeOut в блок completion. Документация может помочь ответить на любые ваши вопросы.

Если по какой-то причине вы не можете использовать блочную версию, вам придется установить делегат ([UIView setAnimationDelegate:(id)delegate]) и селектор с ([UIView setAnimationDidStopSelector:]), на которые делегат будет отвечать.

Снова см. документацию для получения более подробной информации.

person jemmons    schedule 02.01.2014

Моя задача заключалась в том, чтобы этикетка исчезла. А затем исчезайте с измененным текстом. Решение было:

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

    }];
}
person Naloiko Eugene    schedule 27.03.2014

Я настоятельно рекомендую вам использовать общую реализацию, чтобы вы могли повторно использовать код всякий раз, когда вам снова понадобится эффект затухания.

Вы должны создать 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 в качестве параметра завершения, когда вам больше нечего делать после завершения.

Я также рекомендую вам не параметризировать продолжительность, чтобы сохранить шаблон во всем приложении.

Эта реализация может быть использована в будущем для UIButton, UILabel, _11 _... Ну, любого класса, производного от UIView.

person joao.arruda    schedule 05.07.2016

Анимации нарастания и исчезновения можно комбинировать с помощью UIView.animate(withDuration: animations:)

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

Ответ разработчика iPhone на 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)
    }
}
person jglasse    schedule 04.08.2019