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

时间:2012-05-11 19:02:28

标签: ios ipad ios5 core-graphics rounded-corners

我想复制默认iPad日历的事件标记,如下所示:

enter image description here 我正在尝试使用coregraphics,绘制圆形rect的路径。这是我能想到的结果:

enter image description here

正如您所看到的,iPad的版本在圆角处看起来更平滑。我试图使用更大的线宽,看起来像这样: enter image description here

我的代码看起来像这样(从这个网站上获得):

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,但基本上看起来一样。有什么提示吗?

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

enter image description here

2 个答案:

答案 0 :(得分:7)

你的问题是,笔划应用在路径的中心,并且它的一半会被裁剪/遮盖到视图的边界,因为它会在视图之外绘制。如果您在每个方向上将绘图插入一个点,您将获得所需的结果。如果增加笔划的宽度,则需要进一步插入图形(笔划宽度的一半(即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);

答案 1 :(得分:0)

这是因为笔划以路径为中心,这意味着它的一半位于矩形内部而另一半位于外部。

要解决这个问题,请在抚摸之前将笔划宽度和clip to the path加倍。结果是一个内部笔划,它将完全在矩形内。

请注意,剪切到Quartz中的当前路径会重置当前路径,因此您应该create the path as a CGPath以便{@ 3}},剪辑到它,再次添加它并对其进行描边。