以编程方式创建Hexagon图像所需的边框

时间:2016-07-16 06:36:38

标签: ios objective-c uiimageview

我已在滚动视图中以编程方式创建了六边形图像

enter image description here

我希望六边形图像周围有黑色边框,形状与六边形相同。我把六角形图像作为背景,但我没有得到结果。任何人都可以指导我如何获得理想的结果?

以下是创建六边形图像的代码 -

-(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;
}

2 个答案:

答案 0 :(得分:1)

这个概念是正确的,您需要两个形状图层,一个要遮罩,另一个要为边框添加。

但是您要对本地UIView执行此操作,但丢弃您屏蔽的视图并添加该边框,并仅返回遮罩层。您有两种选择:

  • 将屏幕和边框应用于滚动视图中的图像视图,或
  • 拍摄图片或UIView,然后通过拍摄原始图片,应用蒙版和边框,并将其渲染为新的UIImage来创建UIImage

我认为第一种方法可能最简单。如果您为大量图像执行此操作并且不想在运行中执行此操作,则后一种方法很有用。

顺便说一下,你有一个UIGraphicsEndImageContext,但似乎没有开始那个图像上下文。确保这些是平衡的,只有在你采用后一种方法时才这样做,即创建一个新的UIImage,而不是仅仅应用蒙版和边框。

我认为最简单的解决方案是应用蒙版并将边框图层添加到滚动视图中的实际图像视图中,并丢失此UIGraphicsEndImageContext

所以也许你改变你的方法来将掩码和边框应用到你传递给它的UIView,例如:

-(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];
}

我没有检查这一点以确保所有路径创建的东西都是正确的,但基本的想法是采用传递给它的UIView,根据其{{1}进行所有计算然后只需将掩码和边框应用于border(可能是UIView)。

答案 1 :(得分:0)

试试这个

我使用此链接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;
}

结果 enter image description here