Search code examples
iosobjective-cuiviewuiimagecore-animation

UIView Icon Animation


Im trying to do burst animation when the user clicks a view. Im bursting the view into circular pieces when the user clicks a specific view. So I have converted the uiview to uiimage as follows,

   - (UIImage *) imageWithView:(UIView *)view
    {
        UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0);
        [view.layer renderInContext:UIGraphicsGetCurrentContext()];

        UIImage * img = UIGraphicsGetImageFromCurrentImageContext();

        UIGraphicsEndImageContext();

        return img;
    }

Then I have broken the uiimage to pieces as follows,

-(void)splitImage:(UIImage *)image
{
    CGFloat imgWidth = image.size.width/2;
    CGFloat imgheight = image.size.height;
    CGRect leftImgFrame = CGRectMake(0, 0, imgWidth, imgheight);
    CGRect rightImgFrame = CGRectMake(imgWidth, 0, imgWidth, imgheight);

    CGImageRef left = CGImageCreateWithImageInRect(image.CGImage, leftImgFrame);
    CGImageRef right = CGImageCreateWithImageInRect(image.CGImage, rightImgFrame);

    UIImage* leftImage = [UIImage imageWithCGImage:left];
    UIImage* rightImage = [UIImage imageWithCGImage:right];

    CGImageRelease(left);
    CGImageRelease(right);
}

But there are certain issues im facing while doing it.

  1. Im able to break the uiimage into only two pieces but not into dynamic pieces.
  2. How can i show like then uiview is bursting into circular pieces with these broken uiimages?

UPDATE: Following is my updated code...

-(void)startAnimation{


    //Add the initial circle
//    UIView* circleView = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 60, 60)];
    UIView *circleView = [[UIImageView alloc] initWithFrame:self.submit.bounds];

    circleView.bounds = self.submit.bounds;

    CAShapeLayer *circleLayer = [CAShapeLayer layer];

    //set colors
    [circleLayer setStrokeColor:[[UIColor redColor] CGColor]];
    [circleLayer setFillColor:[[UIColor clearColor] CGColor]];
    [circleLayer setPath:[[UIBezierPath bezierPathWithOvalInRect:circleView.bounds] CGPath]];
    [circleView.layer addSublayer:circleLayer];
    [self.view addSubview:circleView];

    //Animate circle
    [circleView setTransform:CGAffineTransformMakeScale(0, 0)];
    [UIView animateWithDuration:0.7 animations:^{
        [circleView setTransform:CGAffineTransformMakeScale(1.3, 1.3)];
    } completion:^(BOOL finished) {
        circleView.hidden = YES;
        //start next animation
        [self createIconAnimation];
    }];
}

-(void)createIconAnimation{

    //load icon which pops up
    UIImageView* iconImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"ic_tick"]];
    iconImage.frame = CGRectMake(50, 50, 60, 60);
    iconImage.bounds = self.submit.bounds;
    [iconImage setTransform:CGAffineTransformMakeScale(0, 0)];
    [self.view addSubview:iconImage];

    //animate icon
    [UIView animateWithDuration:0.3/1.5 animations:^{
        iconImage.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.1, 1.1);
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:0.3/2 animations:^{
            iconImage.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.9, 0.9);
        } completion:^(BOOL finished) {
            [UIView animateWithDuration:0.3/2 animations:^{
                iconImage.transform = CGAffineTransformIdentity;
            }];
        }];
    }];


    //add circles around the icon
    int numberOfCircles = 20;
    CGPoint center = iconImage.center;
    float radius= 35;
    BOOL isBig = YES;;
    for (int i = 0; i<numberOfCircles; i++) {

        float x = radius*cos(M_PI/numberOfCircles*i*2) + center.x;
        float y = radius*sin(M_PI/numberOfCircles*i*2) + center.y;

        float circleRadius = 10;
        if (isBig) {
            circleRadius = 5;
            isBig = NO;
        }else{
            isBig = YES;
        }

        UIView* circleView = [[UIView alloc] initWithFrame:CGRectMake(x, y, circleRadius, circleRadius)];
        CAShapeLayer *circleLayer = [CAShapeLayer layer];
        [circleLayer setStrokeColor:[[UIColor redColor] CGColor]];
        [circleLayer setFillColor:[[UIColor redColor] CGColor]];
        [circleLayer setPath:[[UIBezierPath bezierPathWithOvalInRect:circleView.bounds] CGPath]];
        [circleView.layer addSublayer:circleLayer];
        [self.view addSubview:circleView];

        //animate circles
        [UIView animateWithDuration:0.8 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
            [circleView setTransform:CGAffineTransformMakeTranslation(radius/3*cos(M_PI/numberOfCircles*i*2), radius/3*sin(M_PI/numberOfCircles*i*2))];
            [circleView setTransform:CGAffineTransformScale(circleView.transform, 0.01, 0.01)];
        } completion:^(BOOL finished) {
            circleView.hidden = YES;
        }];


    }

}

The animation has to be on top of the self.submit button but it is not positioned on top of it


Solution

  • Here you go, just add this code to your view controller. It gives you this result:

    http://imgur.com/a/PhcIv

    Just play around with the colors and the animations to get your desired result.

    #import "ViewController.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
    
        [self startAnimation];
    
    }
    
    -(void)startAnimation{
    
        //Add the initial circle
        UIView* circleView = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 60, 60)];
        CAShapeLayer *circleLayer = [CAShapeLayer layer];
    
        //set colors
        [circleLayer setStrokeColor:[[UIColor redColor] CGColor]];
        [circleLayer setFillColor:[[UIColor clearColor] CGColor]];
        [circleLayer setPath:[[UIBezierPath bezierPathWithOvalInRect:circleView.bounds] CGPath]];
        [circleView.layer addSublayer:circleLayer];
        [self.view addSubview:circleView];
    
        //Animate circle
        [circleView setTransform:CGAffineTransformMakeScale(0, 0)];
        [UIView animateWithDuration:0.7 animations:^{
            [circleView setTransform:CGAffineTransformMakeScale(1.3, 1.3)];
        } completion:^(BOOL finished) {
            circleView.hidden = YES;
            //start next animation
            [self createIconAnimation];
        }];
    }
    
    -(void)createIconAnimation{
    
        //load icon which pops up
        UIImageView* iconImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Untitled"]];
        iconImage.frame = CGRectMake(50, 50, 60, 60);
        [iconImage setTransform:CGAffineTransformMakeScale(0, 0)];
        [self.view addSubview:iconImage];
    
        //animate icon
        [UIView animateWithDuration:0.3/1.5 animations:^{
            iconImage.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.1, 1.1);
        } completion:^(BOOL finished) {
            [UIView animateWithDuration:0.3/2 animations:^{
                iconImage.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.9, 0.9);
            } completion:^(BOOL finished) {
                [UIView animateWithDuration:0.3/2 animations:^{
                    iconImage.transform = CGAffineTransformIdentity;
                }];
            }];
        }];
    
    
        //add circles around the icon
        int numberOfCircles = 20;
        CGPoint center = iconImage.center;
        float radius= 35;
        BOOL isBig = YES;;
        for (int i = 0; i<numberOfCircles; i++) {
    
            float x = radius*cos(M_PI/numberOfCircles*i*2) + center.x;
            float y = radius*sin(M_PI/numberOfCircles*i*2) + center.y;
    
            float circleRadius = 10;
            if (isBig) {
                circleRadius = 5;
                isBig = NO;
            }else{
                isBig = YES;
            }
    
            UIView* circleView = [[UIView alloc] initWithFrame:CGRectMake(x, y, circleRadius, circleRadius)];
            CAShapeLayer *circleLayer = [CAShapeLayer layer];
            [circleLayer setStrokeColor:[[UIColor redColor] CGColor]];
            [circleLayer setFillColor:[[UIColor redColor] CGColor]];
            [circleLayer setPath:[[UIBezierPath bezierPathWithOvalInRect:circleView.bounds] CGPath]];
            [circleView.layer addSublayer:circleLayer];
            [self.view addSubview:circleView];
    
            //animate circles
            [UIView animateWithDuration:0.8 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
                [circleView setTransform:CGAffineTransformMakeTranslation(radius/3*cos(M_PI/numberOfCircles*i*2), radius/3*sin(M_PI/numberOfCircles*i*2))];
                [circleView setTransform:CGAffineTransformScale(circleView.transform, 0.01, 0.01)];
            } completion:^(BOOL finished) {
                circleView.hidden = YES;
            }];
    
    
        }
    
    }
    
    
    
    @end