Question

enter image description here

I have a UIImageView with image just like above so what i have to do is gradually decrease and increase the shape of the image.

For achieving above task obviously I have to apply mask so I have created a rounded CAShapeLayer and added to the UIImageView layer and its working fine if I change my radius it will show only that amount of image wrt radius.

My problem is how we can apply animation so it will show in animated form. Please guide me I am not able to achieve with keyframe animation.

Following are the code for masking wrt radius.

// Set up the shape of the circle
int rChange = 0; // Its doing proper masking while changing this value
int radius = 123.5-rChange;

CAShapeLayer *circle = [CAShapeLayer layer];
// Make a circular shape
circle.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0+rChange, 0+rChange, 2.0*radius, 2.0*radius)
                                         cornerRadius:radius].CGPath;

// Configure the apperence of the circle
[circle setFillColor:[[UIColor blackColor] CGColor]];    
[[self.originalImageView layer] setMask:circle];
self.originalImageView.layer.masksToBounds = YES;

where 123.5 is my maximum radius of the image and originalImageView is myUIImageView

Was it helpful?

Solution

If all you want to do is show a brown circle with an animated varying radius, I suggest two changes:

  1. Don't bother with an image. Just use a CAShapeLayer and set its fillColor to brown.

  2. Set the layer's path once, to a circle with width and height of 1 point. Then use the CAShapeLayer's transform to vary the size. You can animate the transform.

For example, create the layer like this:

CGRect bounds = self.view.bounds;

circleLayer = [CAShapeLayer layer];
circleLayer.fillColor = [UIColor brownColor].CGColor;

    circleLayer.position = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds));

// Create a circle with 1-point width/height.
circleLayer.path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 1, 1)].CGPath;

// Use the layer transform to scale the circle up to the size of the view.
[circleLayer setValue:@(bounds.size.width) forKeyPath:@"transform.scale"];

Then you can change its size like this:

[circleLayer setValue:@(newSize) forKeyPath:@"transform.scale"];

That will implicitly (automatically) animate the size change using default parameters. If you want to use different animation parameters, you can explicitly animate the transform:

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
animation.fromValue = [circleLayer valueForKeyPath:@"transform.scale"];
animation.toValue = @(newSize);
animation.duration = 3.0;
animation.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseOut];

// Important: change the actual layer property before installing the animation.
[circleLayer setValue:animation.toValue forKeyPath:animation.keyPath];

// Now install the explicit animation, overriding the implicit animation.
[circleLayer addAnimation:animation forKey:animation.keyPath];
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top