在核心图形中绘制圆角矩形

4

我希望能够复制默认iPad日历的事件标记,它看起来像这样:

图片描述 我试着使用Core Graphics绘制一个圆角矩形路径。这是我能想到的结果:

图片描述

正如你所看到的,iPad版本在圆角处显得更加平滑。我尝试使用更大的线宽,效果如下: 图片描述

我的代码如下(从此网站获取):

UIColor* fillColor= [self.color colorByMultiplyingByRed:1 green:1 blue:1 alpha:0.2];

CGContextSetLineWidth(ctx, 1.0);
CGContextSetStrokeColorWithColor(ctx, self.color.CGColor);
CGContextSetFillColorWithColor(ctx, fillColor.CGColor);

CGRect rrect = self.bounds;

CGFloat radius = 30.0;
CGFloat width = CGRectGetWidth(rrect);
CGFloat height = CGRectGetHeight(rrect);

if (radius > width/2.0)
   radius = width/2.0;

if (radius > height/2.0)
   radius = height/2.0;    

CGFloat minx = CGRectGetMinX(rrect);
CGFloat midx = CGRectGetMidX(rrect);
CGFloat maxx = CGRectGetMaxX(rrect);
CGFloat miny = CGRectGetMinY(rrect);
CGFloat midy = CGRectGetMidY(rrect);
CGFloat maxy = CGRectGetMaxY(rrect);
CGContextMoveToPoint(ctx, minx, midy);
CGContextAddArcToPoint(ctx, minx, miny, midx, miny, radius);
CGContextAddArcToPoint(ctx, maxx, miny, maxx, midy, radius);

CGContextAddArcToPoint(ctx, maxx, maxy, midx, maxy, radius);
CGContextAddArcToPoint(ctx, minx, maxy, minx, midy, radius);
CGContextClosePath(ctx);
CGContextDrawPath(ctx, kCGPathFillStroke);

// draw circle on left side

CGRect target= CGRectMake(rect.origin.x + 4.0, 
                          rect.origin.y + 3.0, 
                          7.0, 7.0);

CGContextSetFillColorWithColor(ctx, self.color.CGColor);
CGContextSetAlpha(ctx, 0.4);
CGContextFillEllipseInRect(ctx, target);

CGContextSetAlpha(ctx, 0.9);
CGContextSetStrokeColorWithColor(ctx, self.color.CGColor);
CGContextStrokeEllipseInRect(ctx, target);

有谁能帮我将结果更接近原始图像吗?我应该使用不同的技术来绘制圆角矩形,或者是否有任何参数可以更改使其看起来更平滑?我已经尝试使用UIBezierPath,但基本上看起来一样。有什么提示吗?

[编辑] 基于CGRectInset的解决方案如下所示:

enter image description here

2个回答

8
你的问题在于描边应用于路径中心,由于其绘制超出视图范围,因此一半描边被裁剪或遮罩。如果你将图形向每个方向缩进一个点,则可以得到所需结果。如果增加描边宽度,则需要进一步缩进图形(缩进量为描边宽度的一半,即4点宽的描边应缩进2点)。
这个问题可以通过更改...进行轻松解决。
CGRect rrect = self.bounds;

转换成

// Inset x and y by half the stroke width (1 point for 2 point stroke) 
CGRect rrect = CGRectInset(self.bounds, 1, 1);

感谢提供代码,已将结果添加在上方。我认为我会选择这个解决方案。虽然还需要调整颜色,但现在的效果我很满意 :) - user826955

0

这是因为描边是以路径为中心的,这意味着它的一半在矩形内部,另一半在外部。

要解决这个问题,您需要将描边宽度加倍,并在描边之前剪切到路径。结果是内部描边,它将完全位于矩形内部。

请注意,在Quartz中剪切到当前路径会重置当前路径,因此您应该将路径创建为CGPath,以便您可以添加它,剪切它,再次添加它并对其进行描边。


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