166 votes

Fondu / Dissoudre lors de la modification de l'image de UIImageView

Plutôt que de créer deux UIImageViews , il semble logique de simplement modifier le image d'une vue. Si je le fais, existe-t-il un fondu / fondu qui se dissolve entre les deux images plutôt qu'un changement instantané?

594voto

algal Points 4298

Il peut être beaucoup plus simple en utilisant les méthodes nouvelles basé sur des blocs, UIKit animation.

Supposons que le code suivant est dans le contrôleur de vue, et le UIImageView vous voulez fondu enchaîné est une sous-vue de self.view adressable via la propriété self.imageView. Puis, tout ce dont vous avez besoin est :

Fait.

Et pour ce faire à Swift, c’est comme si :

46voto

Mirkules Points 996

Edit: il y a une meilleure solution de @algues ci-dessous.

Une autre façon de le faire est en utilisant les CAAnimation transitions:

CATransition *transition = [CATransition animation];
transition.duration = 0.25;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionFade;
transition.delegate = self;
[self.view.layer addAnimation:transition forKey:nil];
view1.hidden = YES;
view2.hidden = NO;

Voir le point de Vue des Transitions exemple de projet à partir d'Apple: http://developer.apple.com/library/ios/#samplecode/ViewTransitions/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007411

6voto

Srikar Appal Points 26892

Oui, ce que vous dites est absolument correct et c'est le moyen de le faire. J'ai écrit cette méthode et je l'utilise toujours pour fondre mon image. Je traite avec CALayer pour cela. Vous devez importer Core Animation pour cela.

 + (void)fadeInLayer:(CALayer *)l
{
    CABasicAnimation *fadeInAnimate   = [CABasicAnimation animationWithKeyPath:@"opacity"];
    fadeInAnimate.duration            = 0.5;
    fadeInAnimate.repeatCount         = 1;
    fadeInAnimate.autoreverses        = NO;
    fadeInAnimate.fromValue           = [NSNumber numberWithFloat:0.0];
    fadeInAnimate.toValue             = [NSNumber numberWithFloat:1.0];
    fadeInAnimate.removedOnCompletion = YES;
    [l addAnimation:fadeInAnimate forKey:@"animateOpacity"];
    return;
}
 

Vous pouvez faire le contraire pour Fade out une image. Après qu'il s'estompe. Vous venez de le supprimer de superview (qui est UIImageView ). [imageView removeFromSuperview] .

4voto

magma Points 4410

Vous pouvez également forfait le fondu d'entrée en fonction dans une sous-classe, de sorte que vous pouvez ensuite l'utiliser comme une commune UIImageView, comme dans l'exemple suivant:

IMMFadeImageView *fiv=[[IMMFadeImageView alloc] initWithFrame:CGRectMake(10, 10, 50, 50)];
[self.view addSubview:fiv];
fiv.image=[UIImage imageNamed:@"initialImage.png"];
fiv.image=[UIImage imageNamed:@"fadeinImage.png"];  // fades in

Une mise en œuvre possible de la façon suivante.

Remarque: la façon dont vous avez réellement mettre en œuvre le fondu dans l' setImage: fonction peut modifier, et pourrait être l'un de l'autre d'excellents exemples décrits dans les autres réponses à cette question - de créer une autre à la volée UIImageView comme je le fais ici pourrait être inacceptable pour les frais généraux de votre situation spécifique.

IMMFadeImageView.h :

#import <UIKit/UIKit.h>

@interface IMMFadeImageView : UIImageView
@property (nonatomic,assign) float fadeDuration;
@end

IMMFadeImageView.m :

#import "IMMFadeImageView.h"

@implementation IMMFadeImageView
@synthesize fadeDuration;

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.fadeDuration=1;
    }
    return self;
}
-(void)setImage:(UIImage *)newImage{

    if(!self.image||self.fadeDuration<=0){
        super.image=newImage;
    } else {
        UIImageView *iv=[[UIImageView alloc] initWithFrame:self.bounds];
        iv.contentMode=self.contentMode;
        iv.image=super.image;
        iv.alpha=1;
        [self addSubview:iv];
        super.image=newImage;
        [UIView animateWithDuration:self.fadeDuration delay:0 options:UIViewAnimationCurveEaseInOut animations:^{
            iv.alpha=0;
        } completion:^(BOOL finished) {
            [iv removeFromSuperview];
        }];
    }
}

Le code ci-dessus repose sur quelques hypothèses (y compris l'ARC d'être activé dans votre projet XCode), est destiné à être utilisé comme une preuve de concept, et dans l'intérêt de la clarté et de la précision, il reste pertinent en omettant importants sans rapport avec le code. Merci de ne pas juste le copier-coller à l'aveuglette.

3voto

Christopher Points 908

J'avais besoin de la transition pour répéter indéfiniment. Il a fallu beaucoup d'essais et d'erreurs pour celui-ci mais j'ai finalement obtenu le résultat final que je cherchais. Ce sont des extraits de code pour ajouter une animation d'image à un UIImageView dans un UITableViewCell.

Voici le code correspondant:

 @interface SomeViewController ()
@property(nonatomic, strong) NSMutableArray *imagesArray;
@property(nonatomic, assign) NSInteger varietyImageAnimationIndex;
@property(nonatomic, assign) BOOL varietyImagesAnimated;
@end

@implementation SomeViewController
@synthesize imagesArray;
@synthesize varietyImageAnimationIndex;
@synthesize varietyImagesAnimated;
...

// NOTE: Initialize the array of images in perhaps viewDidLoad method.

-(void)animateImages
{
    varietyImageAnimationIndex++;

    [UIView transitionWithView:varietyImageView
                      duration:2.0f
                       options:UIViewAnimationOptionTransitionCrossDissolve
                    animations:^{
                        varietyImageView.image = [imagesArray objectAtIndex:varietyImageAnimationIndex % [imagesArray count]];
                    } completion:^(BOOL finished) {
                        [self animateImages];
                    }];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   ...
        [cell.imageView setImage:[imagesArray objectAtIndex:0]];


        [self setVarietyImageView:cell.imageView];

        if (! varietyImagesAnimated)
        {
            varietyImagesAnimated = YES;
            [self animateImages];
        }

    ...
    return cell;
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X