How to add a circular mask to a UIImageview and change the frame and centers while doing so?
Solution 1
Hope this will help
CAShapeLayer *circle = [CAShapeLayer layer];
// Make a circular shape
UIBezierPath *circularPath=[UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, _imgView.frame.size.width, _imgView.frame.size.height) cornerRadius:MAX(_imgView.frame.size.width, _imgView.frame.size.height)];
circle.path = circularPath.CGPath;
// Configure the apperence of the circle
circle.fillColor = [UIColor blackColor].CGColor;
circle.strokeColor = [UIColor blackColor].CGColor;
circle.lineWidth = 0;
imgViewToClipCircular.layer.mask=circle;
Solution 2
Ok, so since the center in my case changes, using the mask is not ging to help. So the easy and clean way is to have a custom UiImageView and clip the draw path.
So for that, subclass UIView
and draw the image inside it and clip the path. Here is the overriden the drawRect
function,
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextAddEllipseInRect(context, self.bounds);
CGContextClip(context);
//The subclass of UIView has a UIImageview as property
[_image drawInRect:rect];
}
FYI, you can not subclass UIImageView itself and override drawRect
, coz it won't call the drawRect
,
The UIImageView class is optimized to draw its images to the display. UIImageView will not call drawRect: a subclass. If your subclass needs custom drawing code, it is recommended you use UIView as the base class.
Comments
-
akshaynhegde almost 2 years
I would like to add a circular mask to UIImageVIew. Here is the function that am using to add the mask..
- (void) addMaskToBounds:(CGRect) maskBounds { CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init]; CGPathRef maskPath = CGPathCreateWithEllipseInRect(maskBounds, NULL); maskLayer.bounds = maskBounds; [maskLayer setPath:maskPath]; [maskLayer setFillColor:[[UIColor blackColor] CGColor]]; maskLayer.position = CGPointMake(maskBounds.size.width/2, maskBounds.size.height/2); [self.imageView.layer setMask:maskLayer]; }
Am able to add the mask but the problem occurs since am changing the image frame and center along with it. The image is enlarged and made small based on the user actions. Hence I would have to add the mask twice when small and when enlarged. So Since am animating the frame change, while animating the image become distorted, or displaced. How do I overcome this ?
I guess its best explained with an example project. Here I have created a Demo project https://github.com/akshaynhegde/MaskImage on GitHub, just run it to see my problem and let me know how resolve the problem.
-
CVertex over 10 yearsThe custom UIImageView solution was what I was previously using, so this solution worked was appropriate for me. It also looks closer to what iOS 7 does
-
Mrug over 9 yearsYou can change centre of mask layer also.
-
Layynezz almost 8 yearsThis doesn't solve the initial question of how to animate frame changes to
UIImageView
when using a mask at all... -
Carl Smith over 7 yearsI found this code very handy because I needed an off-center circular mask for a view I was creating. First I used layer.cornerRadius to make the view circular in Interface Builder. Then I used this code with a negative Y value in the Bezier path to create a mask for it. The resulting shape looks a lot like an American football, which is what I needed.
-
RobP almost 7 yearsNote that your comment is not quite correct -- this subclass of UIView must have a UIImage as a property, not a UIImageView