Search code examples
iphonecocoa-touchcore-animation

Creating a Pop animation similar to the presentation of UIAlertView


I would like to present a view in the same manner as that of UIAlertView - a pop/spring. Unfortunately subclassing UIAlertView is not an option for the view I need to present. I have written some code, but I can't seem to get it as realistic as I would like. I would appreciate any suggestions for greater realism or a link if anything similar has been done (I could not find anything on Google). Thank you.

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

Solution

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