Reputation: 87
I have created a hexagon image programmatically in a scroll view
And I want a black border around that hexagon images, same shape as that of an hexagon. I took a hexagon shape image as an background but I am not getting the result. Can anyone guide me how can I get the desired result?
Here is the code for creating hexagon image-
-(CAShapeLayer*)ChangeShape:(UIView*)view
{
UIView *v = [[UIView alloc] initWithFrame:CGRectMake(_TopList_ImageView.frame.origin.x, _TopList_ImageView.frame.origin.y, _TopList_ImageView.frame.size.width, _TopList_ImageView.frame.size.height)];
// v.backgroundColor = [UIColor purpleColor];
CGRect rect = v.frame;
CAShapeLayer *hexagonMask = [CAShapeLayer layer];
CAShapeLayer *hexagonBorder = [CAShapeLayer layer];
hexagonBorder.frame = v.layer.bounds;
UIBezierPath *hexagonPath = [UIBezierPath bezierPath];
CGFloat sideWidth = 2 * ( 0.5 * rect.size.width / 2 );
CGFloat lcolumn = ( rect.size.width - sideWidth ) / 2;
CGFloat rcolumn = rect.size.width - lcolumn;
CGFloat height = 0.866025 * rect.size.height;
CGFloat y = (rect.size.height - height) / 2;
CGFloat by = rect.size.height - y;
CGFloat midy = rect.size.height / 2;
CGFloat rightmost = rect.size.width;
[hexagonPath moveToPoint:CGPointMake(lcolumn, y)];
[hexagonPath addLineToPoint:CGPointMake(rcolumn, y)];
[hexagonPath addLineToPoint:CGPointMake(rightmost, midy)];
[hexagonPath addLineToPoint:CGPointMake(rcolumn, by)];
[hexagonPath addLineToPoint:CGPointMake(lcolumn, by)];
[hexagonPath addLineToPoint:CGPointMake(0, midy)];
[hexagonPath addLineToPoint:CGPointMake(lcolumn, y)];
hexagonMask.path = hexagonPath.CGPath;
hexagonBorder.path = hexagonPath.CGPath;
hexagonBorder.fillColor = [UIColor clearColor].CGColor;
hexagonBorder.strokeColor = [UIColor blackColor].CGColor;
hexagonBorder.lineWidth = 5;
v.layer.mask = hexagonMask;
[v.layer addSublayer:hexagonBorder];
// hexagonMask.path = path.CGPath;
UIGraphicsEndImageContext();
return hexagonMask;
}
Upvotes: 0
Views: 214
Reputation: 437552
The concept is right, that you want two shape layers, one to mask, and one that you'll add for the border.
But you're doing this to a local UIView
, but discarding that view to which you masked and added that border, and only returning the mask layer. You have two options:
UIView
, and create a UIImage
by taking the original image, applying the mask and border, and rendering this as a new UIImage
. I think the first approach is probably easiest. The latter approach is useful if you're doing this for tons of images and don't want to do this on the fly.
As an aside, you have a UIGraphicsEndImageContext
, but don't appear to begin that image context. Make sure those are balanced, and only do that if you're doing that latter approach, namely creating a new UIImage
, not if just applying the mask and border.
The easiest solution in my opinion, is to apply the mask and add the border layer to the actual image views in the scroll view and lose this UIGraphicsEndImageContext
.
So perhaps you change your method to apply mask and border to the UIView
you passed to this, e.g.:
-(void) applyHexagonMaskAndBorderToView:(UIView*)view {
CGRect rect = view.bounds;
CAShapeLayer *hexagonMask = [CAShapeLayer layer];
CAShapeLayer *hexagonBorder = [CAShapeLayer layer];
hexagonBorder.frame = view.layer.bounds;
UIBezierPath *hexagonPath = [UIBezierPath bezierPath];
CGFloat sideWidth = 2 * ( 0.5 * rect.size.width / 2 );
CGFloat lcolumn = ( rect.size.width - sideWidth ) / 2;
CGFloat rcolumn = rect.size.width - lcolumn;
CGFloat height = 0.866025 * rect.size.height;
CGFloat y = (rect.size.height - height) / 2;
CGFloat by = rect.size.height - y;
CGFloat midy = rect.size.height / 2;
CGFloat rightmost = rect.size.width;
[hexagonPath moveToPoint:CGPointMake(lcolumn, y)];
[hexagonPath addLineToPoint:CGPointMake(rcolumn, y)];
[hexagonPath addLineToPoint:CGPointMake(rightmost, midy)];
[hexagonPath addLineToPoint:CGPointMake(rcolumn, by)];
[hexagonPath addLineToPoint:CGPointMake(lcolumn, by)];
[hexagonPath addLineToPoint:CGPointMake(0, midy)];
[hexagonPath addLineToPoint:CGPointMake(lcolumn, y)];
hexagonMask.path = hexagonPath.CGPath;
hexagonBorder.path = hexagonPath.CGPath;
hexagonBorder.fillColor = [UIColor clearColor].CGColor;
hexagonBorder.strokeColor = [UIColor blackColor].CGColor;
hexagonBorder.lineWidth = 5;
view.layer.mask = hexagonMask;
[view.layer addSublayer:hexagonBorder];
}
I haven't checked this to make sure that all of the path creation stuff is right, but the basic idea is take the UIView
that was passed to this, do all calculations based upon its border
and then just apply the mask and border to that UIView
(possibly a UIImageView
).
Upvotes: 1
Reputation: 2786
plz try this
i use this link How to round corners of UIImage with Hexagon mask
IBOutlet UIImageView *yoruImageView;
CGFloat lineWidth = 5.0;
UIBezierPath *path = [self roundedPolygonPathWithRect:image.bounds
lineWidth:lineWidth
sides:6
cornerRadius:30];
CAShapeLayer *mask = [CAShapeLayer layer];
mask.path = path.CGPath;
mask.lineWidth = lineWidth;
mask.strokeColor = [UIColor clearColor].CGColor;
mask.fillColor = [UIColor whiteColor].CGColor;
yoruImageView.layer.mask = mask;
CAShapeLayer *border = [CAShapeLayer layer];
border.path = path.CGPath;
border.lineWidth = lineWidth;
border.strokeColor = [UIColor blackColor].CGColor;
border.fillColor = [UIColor clearColor].CGColor;
[yoruImageView.layer addSublayer:border];
-(UIBezierPath *)roundedPolygonPathWithRect:(CGRect)square lineWidth:(CGFloat)lineWidth sides:(NSInteger)sides cornerRadius:(CGFloat)cornerRadius {
UIBezierPath *path = [UIBezierPath bezierPath];
CGFloat theta = 2.0 * M_PI / sides; // how much to turn at every corner
CGFloat offset = cornerRadius * tanf(theta / 2.0); // offset from which to start rounding corners
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/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 - offset, 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 - offset * 2.0) * cosf(angle), point.y + (sideLength - offset * 2.0) * sinf(angle));
[path addLineToPoint:point];
CGPoint center = CGPointMake(point.x + cornerRadius * cosf(angle + M_PI_2), point.y + cornerRadius * sinf(angle + M_PI_2));
[path addArcWithCenter:center radius:cornerRadius startAngle:angle - M_PI_2 endAngle:angle + theta - M_PI_2 clockwise:YES];
point = path.currentPoint; // we don't have to calculate where the arc ended ... UIBezierPath did that for us
angle += theta;
}
[path closePath];
return path;
}
Upvotes: 1