2011-12-01 14 views
7

Tengo 2 imágenes. Uno está en la parte posterior del otro. Quiero desvanecer la imagen superior comenzando desde la esquina izquierda. ¿Cómo puedo hacer esto?¿Cómo aplicar desvanecimiento parcial en IOS?

¿Debo usar gradiente de máscara?

+0

¿Está utilizando dos UIImageViews? ¿Dos CALayers? –

+0

No me importa. Puedo usar cualquiera de ellos – Burak

Respuesta

11

Aquí hay una técnica que se desvanecerá todo lo que hay en un CALayer, desde la parte superior izquierda a la inferior derecha, revelando lo que está debajo del CALayer.

Digamos que vamos a atenuar la capa de un UIImageView llamado self.fadeView.

Crearemos un CAGradientLayer y úselo como self.fadeView.layer.mask. El gradiente pasará de alfa = 0 (transparente) a alfa = 1 (opaco) usando cuatro paradas: 0, 0, 1, 1. Sí, dos ceros y luego dos unos. Cuando queremos que fadeView sea opaco, estableceremos las ubicaciones de detención en -1, -.5, 0, 1. De esta forma, las dos paradas alfa = 0 están completamente fuera de los límites de la capa. Cuando queremos que fadeView sea transparente, estableceremos las ubicaciones de detención en 0, 1, 1.5, 2. De esta forma, las dos paradas alfa = 1 están completamente fuera de los límites de la capa. El CAGradientLayer animará automáticamente los cambios a sus ubicaciones de detención, creando un efecto de fundido cruzado.

Aquí está el código:

#import "ViewController.h" 

@implementation ViewController 

@synthesize fadeView = _fadeView; 

static NSArray *locations(float a, float b, float c, float d) 
{ 
    return [NSArray arrayWithObjects: 
     [NSNumber numberWithFloat:a], 
     [NSNumber numberWithFloat:b], 
     [NSNumber numberWithFloat:c], 
     [NSNumber numberWithFloat:d], 
     nil]; 
} 

// In my test project, I put a swipe gesture recognizer on fadeView in my XIB 
// with direction = Up and connected it to this action. 
- (IBAction)fadeIn 
{ 
    [CATransaction begin]; 
    [CATransaction setValue:[NSNumber numberWithDouble:2.0] forKey:kCATransactionAnimationDuration]; 
    ((CAGradientLayer *)self.fadeView.layer.mask).locations = locations(-1, -.5, 0, 1); 
    [CATransaction commit]; 
} 

// In my test project, I put a swipe gesture recognizer on fadeView in my XIB 
// with direction = Down and connected it to this action. 
- (IBAction)fadeOut 
{ 
    [CATransaction begin]; 
    [CATransaction setValue:[NSNumber numberWithDouble:2.0] forKey:kCATransactionAnimationDuration]; 
    ((CAGradientLayer *)self.fadeView.layer.mask).locations = locations(0, 1, 1.5, 2); 
    [CATransaction commit]; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    CAGradientLayer *mask = [CAGradientLayer layer]; 
    mask.frame = self.fadeView.bounds; 
    mask.colors = [NSArray arrayWithObjects: 
     (__bridge id)[UIColor clearColor].CGColor, 
     (__bridge id)[UIColor clearColor].CGColor, 
     (__bridge id)[UIColor whiteColor].CGColor, 
     (__bridge id)[UIColor whiteColor].CGColor, 
     nil]; 
    mask.startPoint = CGPointZero; // top left corner 
    mask.endPoint = CGPointMake(1, 1); // bottom right corner 
    self.fadeView.layer.mask = mask; 
    [self fadeIn]; // initialize mask.locations 
} 

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    // Return YES for supported orientations 
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 
} 

@end 
+0

Gracias, pero no pude hacer que el código funcione. ¿Tienes un proyecto de muestra? – Burak

+1

http://www.dqd.com/~mayoff/crossfadetest.zip –

+0

¡Exactamente lo que necesito! ¡¡Muchas gracias!! – Burak

2

Defina su propia subclase CALayer con su propia animación actionForKey para la clave contents.

@interface CustomLayer: CALayer 

@end 

@implementation CustomLayer 


+ (id<CAAction>)actionForKey:(NSString*)event { 

if ([event isEqualToString:@"contents"]) { 
    CATransition* basicAnimation = [CATransition animation]; 
    basicAnimation.type = kCATransitionMoveIn; 
    basicAnimation.subtype = kCATransitionFromLeft; 
    return basicAnimation; 
} else { 
    return nil; 
} 
} 

@end 

Haciendo así, cada vez que se establece la propiedad contents de su objeto CustomLayer, se mostrará la transición:

CustomLayer* layer = [CustomLayer layer]; 
layer.contents = <FIRST_CGIMAGEREF_HERE>; 
... 
layer.contents = <SECOND_CGIMAGEREF_HERE>; 

Como es habitual, se puede envolver la asignación de propiedad en una transacción:

[CATransaction begin]; 
    .... 
[CATransaction end]; 

si desea más control sobre la duración de la transición, pero en cualquier caso se aplicará la transición.

EDIT:

Para el tipo de transición que le gustaría tener, usted puede echar un vistazo a this sample on GitHub. Busque la ShutterTransition. No es exactamente lo que estás buscando, pero podría llevarte por el camino correcto.

+0

Creo que su sugerencia es para la transición. Lo que necesito es algo como http://vimeo.com/32931599 – Burak

Cuestiones relacionadas