Reputation: 629
I want to programatically crop a shape over my UIImageView. I know about creating a path with QuartzCore, but I don't understand context. Give me an example by subclassing UIImageView.
So how can I make an image go from this:
To this:
I also need the mask to be transparent
Upvotes: 3
Views: 1274
Reputation: 438257
The easiest approach is to
UIBezierPath
for the hexagon;CAShapeLayer
from that path; andCAShapeLayer
as a mask to the image view's layer
.Thus, it might look like:
CAShapeLayer *mask = [CAShapeLayer layer];
mask.path = [[self polygonPathWithRect:self.imageView.bounds lineWidth:0.0 sides:6] CGPath];
mask.strokeColor = [UIColor clearColor].CGColor;
mask.fillColor = [UIColor whiteColor].CGColor;
self.imageView.layer.mask = mask;
where
/** Create UIBezierPath for regular polygon inside a CGRect
*
* @param square The CGRect of the square in which the path should be created.
* @param lineWidth The width of the stroke around the polygon. The polygon will be inset such that the stroke stays within the above square.
* @param sides How many sides to the polygon (e.g. 6=hexagon; 8=octagon, etc.).
*
* @return UIBezierPath of the resulting polygon path.
*/
- (UIBezierPath *)polygonPathWithRect:(CGRect)square
lineWidth:(CGFloat)lineWidth
sides:(NSInteger)sides
{
UIBezierPath *path = [UIBezierPath bezierPath];
CGFloat theta = 2.0 * M_PI / sides; // how much to turn at every corner
CGFloat squareWidth = MIN(square.size.width, square.size.height); // width of the square
// calculate the length of the sides of the polygon
CGFloat length = squareWidth - lineWidth;
if (sides % 4 != 0) { // if not dealing with polygon which will be square with all sides ...
length = length * cosf(theta / 2.0); // ... offset it inside a circle inside the square
}
CGFloat sideLength = length * tanf(theta / 2.0);
// start drawing at `point` in lower right corner
CGPoint point = CGPointMake(squareWidth / 2.0 + sideLength / 2.0, squareWidth - (squareWidth - length) / 2.0);
CGFloat angle = M_PI;
[path moveToPoint:point];
// draw the sides and rounded corners of the polygon
for (NSInteger side = 0; side < sides; side++) {
point = CGPointMake(point.x + sideLength * cosf(angle), point.y + sideLength * sinf(angle));
[path addLineToPoint:point];
angle += theta;
}
[path closePath];
return path;
}
I posted another answer that illustrates the idea with rounded corners, too.
If you want to implement the addition of this mask as part of a UIImageView
subclass, I'll leave that to you. But hopefully this illustrates the basic idea.
Upvotes: 4