2008-10-17 8 views
19

Implementé un visor de imágenes bastante simple que permitirá al usuario navegar a través de una colección de imágenes. Se cargan desde Internet y se muestran en el dispositivo a través de un objeto UIImageView. Algo como esto:La mejor manera de transición entre dos imágenes en un UIImageView

UIImage *image = [[UIImage alloc] initWithData:imageData]; 
[img setImage:image]; 

imageData es una instancia de NSData que utilizo para cargar el contenido de la imagen desde una URL, y img es la UIImageView ejemplo.

Todo funciona bien, pero la nueva imagen reemplaza a la que se muestra antes sin transiciones, y me preguntaba si hay una manera fácil de hacer una buena transición de animación para mejorar la experiencia del usuario.

¿Alguna idea de cómo hacer esto? Las muestras de código serían muy apreciadas.

+2

Para aquellos de nosotros hojearlo sería genial si alguien pudiera seleccionar una respuesta. Dado que este usuario parece haber dejado un poco de cómo ... – Mytheral

Respuesta

3

El truco está en hacer dos instancias de UIImageView. Las intercambias entre llamadas a UIView + beginAnimations y + commitAnimations.

1

Hay varias maneras de hacerlo y estoy de acuerdo con Ben View Transitions es un gran ejemplo. Si está buscando transiciones simples de pantalla completa, solo consideraría comenzar una nueva aplicación de utilidad y observar el método toggleView en RootViewController.m. Intente desconectar UIViewAnimationTransitionFlipFromLeft y UIViewAnimationTransitionFlipFromRight a UIViewAnimationTransitionCurlUp y UIViewAnimationTransitionCurlDown para obtener un efecto de transición realmente agradable (esto solo funciona en el dispositivo).

3

Nada diferente de lo que se ha explicado, pero en el código, estas son las transiciones disponibles:

typedef enum { 
     UIViewAnimationTransitionNone, 
     UIViewAnimationTransitionFlipFromLeft, 
     UIViewAnimationTransitionFlipFromRight, 
     UIViewAnimationTransitionCurlUp, 
     UIViewAnimationTransitionCurlDown, 
    } UIViewAnimationTransition; 

Código(poner esto en una devolución de llamada como touchesEnded):

CGContextRef context = UIGraphicsGetCurrentContext(); 
[UIView beginAnimations:nil context:context]; 

[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromLeft forView:[self superview] cache:YES]; 

// -- These don't work on the simulator and the curl up will turn into a fade -- // 
//[UIView setAnimationTransition: UIViewAnimationTransitionCurlUp forView:[self superview] cache:YES]; 
//[UIView setAnimationTransition: UIViewAnimationTransitionCurlDown forView:[self superview] cache:YES]; 

[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 
[UIView setAnimationDuration:1.0]; 

// Below assumes you have two subviews that you're trying to transition between 
[[self superview] exchangeSubviewAtIndex:0 withSubviewAtIndex:1]; 
[UIView commitAnimations]; 
0

aquí es lo que he hecho: un desvanecimiento. pongo otro UIImageView con el mismo UIImage y dimensión llamado tmp. reemplazo el UIImage de la base UIImageView. Luego pongo la imagen de la derecha en la base (todavía cubierta por tmp).

El siguiente paso es - para configurar alfa de tmp a cero, - para estirar la UIImageView de base a la proporción de la derecha de la nueva UIImage basado en la altura de la base.

Aquí está el código:

UIImage *img = [params objectAtIndex:0]; // the right image 
UIImageView *view = [params objectAtIndex:1]; // the base 

UIImageView *tmp = [[UIImageView alloc] initWithImage:view.image]; // the one which will use to fade 
tmp.frame = CGRectMake(0, 0, view.frame.size.width, view.frame.size.height); 
[view addSubview:tmp]; 

view.image = img; 
float r = img.size.width/img.size.height; 
float h = view.frame.size.height; 
float w = h * r; 
float x = view.center.x - w/2; 
float y = view.frame.origin.y; 

[UIView beginAnimations:nil context:nil]; 
[UIView setAnimationDuration:1.0]; 

tmp.alpha = 0; 
view.frame = CGRectMake(x, y, w, h); 

[UIView commitAnimations]; 

[tmp performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:1.5]; 
[tmp performSelector:@selector(release) withObject:nil afterDelay:2]; 
13

Estaba a través de su correo y tenía exactamente el mismo requisito. El problema con todas las soluciones anteriores es que tendrá que incorporar la lógica de la transición a su controlador. En el sentido, el enfoque no es modular. En lugar de escribir este subclase de UIImageView: archivo

TransitionImageView.h:

#import <UIKit/UIKit.h> 


@interface TransitionImageView : UIImageView 
{ 
    UIImageView *mOriginalImageViewContainerView; 
    UIImageView *mIntermediateTransitionView; 
} 
@property (nonatomic, retain) UIImageView *originalImageViewContainerView; 
@property (nonatomic, retain) UIImageView *intermediateTransitionView; 

#pragma mark - 
#pragma mark Animation methods 
-(void)setImage:(UIImage *)inNewImage withTransitionAnimation:(BOOL)inAnimation; 

@end 

TransitionImageView.m archivo:

#import "TransitionImageView.h" 

#define TRANSITION_DURATION 1.0 

@implementation TransitionImageView 
@synthesize intermediateTransitionView = mIntermediateTransitionView; 
@synthesize originalImageViewContainerView = mOriginalImageViewContainerView; 

- (id)initWithFrame:(CGRect)frame { 
    if ((self = [super initWithFrame:frame])) { 
     // Initialization code 
    } 
    return self; 
} 

/* 
// Only override drawRect: if you perform custom drawing. 
// An empty implementation adversely affects performance during animation. 
- (void)drawRect:(CGRect)rect { 
    // Drawing code 
} 
*/ 

- (void)dealloc 
{ 
    [self setOriginalImageViewContainerView:nil]; 
    [self setIntermediateTransitionView:nil]; 
    [super dealloc]; 
} 

#pragma mark - 
#pragma mark Animation methods 
-(void)setImage:(UIImage *)inNewImage withTransitionAnimation:(BOOL)inAnimation 
{ 
    if (!inAnimation) 
    { 
     [self setImage:inNewImage]; 
    } 
    else 
    { 
     // Create a transparent imageView which will display the transition image. 
     CGRect rectForNewView = [self frame]; 
     rectForNewView.origin = CGPointZero; 
     UIImageView *intermediateView = [[UIImageView alloc] initWithFrame:rectForNewView]; 
     [intermediateView setBackgroundColor:[UIColor clearColor]]; 
     [intermediateView setContentMode:[self contentMode]]; 
     [intermediateView setClipsToBounds:[self clipsToBounds]]; 
     [intermediateView setImage:inNewImage]; 

     // Create the image view which will contain original imageView's contents: 
     UIImageView *originalView = [[UIImageView alloc] initWithFrame:rectForNewView]; 
     [originalView setBackgroundColor:[UIColor clearColor]]; 
     [originalView setContentMode:[self contentMode]]; 
     [originalView setClipsToBounds:[self clipsToBounds]]; 
     [originalView setImage:[self image]]; 

     // Remove image from the main imageView and add the originalView as subView to mainView: 
     [self setImage:nil]; 
     [self addSubview:originalView]; 

     // Add the transparent imageView as subview whose dimensions are same as the view which holds it. 
     [self addSubview:intermediateView]; 

     // Set alpha value to 0 initially: 
     [intermediateView setAlpha:0.0]; 
     [originalView setAlpha:1.0]; 
     [self setIntermediateTransitionView:intermediateView]; 
     [self setOriginalImageViewContainerView:originalView]; 
     [intermediateView release]; 
     [originalView release]; 

     // Begin animations: 
     [UIView beginAnimations:@"ImageViewTransitions" context:nil]; 
     [UIView setAnimationDuration:(double)TRANSITION_DURATION]; 
     [UIView setAnimationDelegate:self]; 
     [UIView setAnimationCurve:UIViewAnimationCurveEaseOut]; 
     [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)]; 
     [[self intermediateTransitionView] setAlpha:1.0]; 
     [[self originalImageViewContainerView] setAlpha:0.0]; 
     [UIView commitAnimations]; 
    } 
} 

-(void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context 
{ 
    // Reset the alpha of the main imageView 
    [self setAlpha:1.0]; 

    // Set the image to the main imageView: 
    [self setImage:[[self intermediateTransitionView] image]]; 

    [[self intermediateTransitionView] removeFromSuperview]; 
    [self setIntermediateTransitionView:nil]; 

    [[self originalImageViewContainerView] removeFromSuperview]; 
    [self setOriginalImageViewContainerView:nil]; 
} 

@end 

Usted puede incluso reemplazar el método de UIImageView -setImage y llamar a mi método -setImage:withTransitionAnimation:. Si se hace así, asegúrese de llamar al [super setImage:] en lugar de [self setImage:] en el método -setImage:withTransitionAnimation: para que no termine en una llamada infinita recursiva.

-Raj

8
[UIView 
    animateWithDuration:0.2 
    delay:0 
    options:UIViewAnimationCurveEaseOut 
    animations:^{ 
     self.view0.alpha = 0; 
     self.view1.alpha = 1; 
    } 
    completion:^(BOOL finished){ 
     view0.hidden = YES; 
    } 
]; 
3

Por favor marque la respuesta. Creo que está buscando esto:

imgvw.image=[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"Your Image name as string"]]]; 
CATransition *transition = [CATransition animation]; 
transition.duration = 1.0f; 
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
transition.type = kCATransitionFade; 
[imgvw.layer addAnimation:transition forKey:nil]; 
+0

Esto funciona bien, especialmente con subtipos de inserción y de transición. Creo que es la respuesta óptima, ya que no requiere la creación de vistas adicionales falsas ni la manipulación de su geometría. – SG1

Cuestiones relacionadas