Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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];
}
like image 563
RunLoop Avatar asked Apr 22 '10 12:04

RunLoop


3 Answers

- (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"]; } 
like image 98
zoul Avatar answered Sep 30 '22 11:09

zoul


the pointer to delackner's post is the best initial one i found as well. i would only offer for folks trying to really mimic UIAlertView a few things:

  1. adding the rounded edges, border, and semi-transparent layer color
  2. some alpha fade-in/-out, and
  3. redoing with blocks as somewhat more succinct with latest iOS toolchain
  4. i also found the initial 1.1 scale-out he suggests too large, 1.05 seemed more correct visually to me in most cases

Code:

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;
                                                       }
                                       ];
                                    }
                    ];
                 }
 ];
like image 40
natbro Avatar answered Sep 30 '22 12:09

natbro


One thing: multi-step animations like this are much easier if you use a CAKeyframeAnimation instead of mutiple UIView queued animations.

like image 35
Ole Begemann Avatar answered Sep 30 '22 12:09

Ole Begemann