2010-04-22 6 views
23

Me gustaría presentar una vista de la misma manera que la de UIAlertView - un pop/spring. Desafortunadamente, subclasificar UIAlertView no es una opción para la vista que necesito presentar. He escrito un código, pero parece que no puedo obtenerlo tan realista como me gustaría. Agradecería cualquier sugerencia para un mayor realismo o un enlace si se hubiera hecho algo similar (no pude encontrar nada en Google). Gracias.Creando una animación Pop similar a la presentación de UIAlertView

- (id)initWithFrame:(CGRect)frame { 
    if ((self = [super initWithFrame:frame])) { 

     self.backgroundColor = [UIColor whiteColor]; 

     v = [[UIView alloc] initWithFrame:CGRectMake(140, 140, 60, 60)]; 
     v.backgroundColor = [UIColor blueColor]; 

     [self addSubview:v]; 
     [self animate]; 

    } 
    return self; 
} 

- (void)animate { 

    [UIView beginAnimations:nil context:NULL]; 
    [UIView setAnimationCurve:UIViewAnimationCurveLinear]; 
    [UIView setAnimationDuration:0.2]; 
    [UIView setAnimationDelegate:self]; 
    [UIView setAnimationDidStopSelector:@selector(popStep1Complete)]; 
    v.frame = CGRectMake(90, 90, 140, 140); 
    [UIView commitAnimations]; 
} 

- (void)popStep1Complete { 

    [UIView beginAnimations:nil context:NULL]; 
    [UIView setAnimationCurve:UIViewAnimationCurveLinear]; 
    [UIView setAnimationDuration:0.15]; 
    [UIView setAnimationDelegate:self]; 
    [UIView setAnimationDidStopSelector:@selector(popStep2Complete)]; 
    v.frame = CGRectMake(110, 110, 100, 100); 
    [UIView commitAnimations]; 
} 

- (void)popStep2Complete { 

    [UIView beginAnimations:nil context:NULL]; 
    [UIView setAnimationCurve:UIViewAnimationCurveLinear]; 
    [UIView setAnimationDuration:0.15]; 
    v.frame = CGRectMake(100, 100, 120, 120); 
    [UIView commitAnimations]; 
} 

Respuesta

77
- (void) attachPopUpAnimation 
{ 
    CAKeyframeAnimation *animation = [CAKeyframeAnimation 
     animationWithKeyPath:@"transform"]; 

    CATransform3D scale1 = CATransform3DMakeScale(0.5, 0.5, 1); 
    CATransform3D scale2 = CATransform3DMakeScale(1.2, 1.2, 1); 
    CATransform3D scale3 = CATransform3DMakeScale(0.9, 0.9, 1); 
    CATransform3D scale4 = CATransform3DMakeScale(1.0, 1.0, 1); 

    NSArray *frameValues = [NSArray arrayWithObjects: 
     [NSValue valueWithCATransform3D:scale1], 
     [NSValue valueWithCATransform3D:scale2], 
     [NSValue valueWithCATransform3D:scale3], 
     [NSValue valueWithCATransform3D:scale4], 
     nil]; 
    [animation setValues:frameValues]; 

    NSArray *frameTimes = [NSArray arrayWithObjects: 
     [NSNumber numberWithFloat:0.0], 
     [NSNumber numberWithFloat:0.5], 
     [NSNumber numberWithFloat:0.9], 
     [NSNumber numberWithFloat:1.0], 
     nil];  
    [animation setKeyTimes:frameTimes]; 

    animation.fillMode = kCAFillModeForwards; 
    animation.removedOnCompletion = NO; 
    animation.duration = .2; 

    [self.layer addAnimation:animation forKey:@"popup"]; 
} 
+0

¿A dónde va esto? En mi vista principal o mi UIAlertView? – Moshe

+0

Cualquier subclase de 'UIView'. En este caso, la clase personalizada 'UIAlertView'. – zoul

+0

La segunda vez que la animación no se activó, la configuración de la clave nil me solucionó el problema: [auto.view.layer addAnimation: animation forKey: nil]; – amleszk

5

Una cosa: animaciones de varios pasos de este tipo son mucho más fácil si se utiliza un CAKeyframeAnimation en lugar de mutiple UIView cola animaciones.

+3

Gracias, pero podría eliminar su respuesta e incluirla como comentario porque esta pregunta ahora aparece como respondida. – RunLoop

+9

No, no lo haré, lo siento. Si bien me doy cuenta de que mi respuesta no es lo que quería escuchar y es solo una solución parcial, es IMO una respuesta válida porque es un enfoque mucho mejor para el problema que el código que publicó. –

7

el puntero a la publicación de delackner es el mejor inicial que encontré también. Yo sólo iba a ofrecer para la gente que tratan de imitar realmente UIAlertView algunas cosas:

  1. añadiendo los bordes redondeados, borde y semitransparente color de la capa
  2. algunos alfa fundido de entrada/salida privado, y
  3. haciendo de nuevo con bloques como algo más sucinta con último iOS cadena de herramientas
  4. también encontré la escala de 1.1 de salida inicial que sugiere demasiado grande, 1,05 parecía más correcto visualmente a mí en la mayoría de los casos

Código:

self.layer.cornerRadius = 10.0; 
[self.layer setMasksToBounds:YES]; 
self.layer.backgroundColor = [[UIColor blueColor] colorWithAlphaComponent:0.60].CGColor; 
self.layer.borderColor = [UIColor whiteColor].CGColor; 
self.layer.borderWidth = 1.1; 
if (self.hidden == YES) { // swoop in if coming from hidden, otherwise pulse in-place 
    self.transform = CGAffineTransformMakeScale(0.6, 0.6); 
} 
self.hidden = NO; 
[UIView animateWithDuration:0.2 
       animations:^{ 
        self.transform = CGAffineTransformMakeScale(1.05, 1.05); 
        self.alpha = 0.8; 
       } 
       completion:^(BOOL finished){ 
        [UIView animateWithDuration:1/15.0 
            animations:^{ 
             self.transform = CGAffineTransformMakeScale(0.9, 0.9); 
             self.alpha = 0.9; 
            } 
            completion:^(BOOL finished) { 
             [UIView animateWithDuration:1/7.5 
                 animations:^{ 
                 self.transform = CGAffineTransformIdentity;                
                 self.alpha = 1.0; 
                 } 
             ]; 
            } 
        ]; 
       } 
]; 
Cuestiones relacionadas