填充路径后无法描边

23

以下代码很好地创建了一个由CGRect(rectRect)定义的圆角矩形。

它填充得很好,但我看不到描边。有任何想法为什么我看不到描边吗?

-(void)drawRect:(CGRect)rect {

    CGContextRef ctx = UIGraphicsGetCurrentContext();

    CGContextSetRGBFillColor(ctx, 0, 0, 0, 0.4);
    CGContextSetRGBStrokeColor(ctx, 1, 1, 1, 1);
    CGContextSetLineWidth(ctx, 4.0);

    float fw, fh;
    rect = rectRect;
    float ovalWidth = 12;
    float ovalHeight = 12;

    if (ovalWidth == 0 || ovalHeight == 0) {
        CGContextAddRect(ctx, rect);
        return;
    }

    CGContextTranslateCTM (ctx, CGRectGetMinX(rect), CGRectGetMinY(rect));
    CGContextScaleCTM (ctx, ovalWidth, ovalHeight);
    fw = CGRectGetWidth (rect) / ovalWidth;
    fh = CGRectGetHeight (rect) / ovalHeight;
    CGContextMoveToPoint(ctx, fw, fh/2);
    CGContextAddArcToPoint(ctx, fw, fh, fw/2, fh, 1);
    CGContextAddArcToPoint(ctx, 0, fh, 0, fh/2, 1);
    CGContextAddArcToPoint(ctx, 0, 0, fw/2, 0, 1);
    CGContextAddArcToPoint(ctx, fw, 0, fw, fh/2, 1);
    CGContextClosePath(ctx);

    CGContextFillPath(ctx);
    CGContextStrokePath(ctx);

}
2个回答

59

当你通过描边或填充来绘制路径时,图形上下文会将其路径重置为空。因此,在调用CGContextFillPath之后,上下文没有路径可描边。

不要尝试先填充路径再描边,你可以使用CGContextDrawPath函数在一次调用中同时完成两个操作:

CGContextDrawPath(ctx, kCGPathFillStroke);

kCGPathFillStroke常量告诉Core Graphics先填充路径,然后描边。

另一方面,您可以使用UIBezierPathUIColor来大幅减少代码量:

-(void)drawRect:(CGRect)rect {
    [[UIColor colorWithWhite:0 alpha:0.4] setFill];
    [[UIColor whiteColor] setStroke];

    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rectRect cornerRadius:12];
    path.lineWidth = 4;
    [path fill];
    [path stroke];
}

顺便问一下,UIBezierPath选项是高性能修复吗?当然它完美地工作了。还是我应该寻找其他的解决方案? - OWolf
不要担心性能,直到Instruments告诉你瓶颈在哪里。 - rob mayoff
我已经修改了我的答案,避免复制路径。 - rob mayoff

8

Swift 5 版本,重点内容如下:

override func draw(_ rect: CGRect) {
    guard let context = UIGraphicsGetCurrentContext() else { return }
    context.move(...) // Make path
    context.addLine(...)
    ...
    context.closePath()
    context.setLineWidth(lineWidth)
    context.setStrokeColor(strokeColor!.cgColor)
    context.setFillColor(fillColor!.cgColor)
    context.drawPath(using: .fillStroke) // Fill and stroke
}

这对我解决了问题,我成功地实现了填充颜色和不同的边框颜色。 - AleGiovane

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接