我有以下代码:
- (void)drawRect:(CGRect)rect {
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(c, [UIColor blackColor].CGColor);
CGContextFillRect(c, rect);
CGContextSetLineJoin(c, kCGLineJoinRound);
CGContextSetLineCap(c, kCGLineCapRound);
CGContextSetLineWidth(c, 50.0);
CGContextSetStrokeColorWithColor(c, [UIColor redColor].CGColor);
CGContextBeginPath(c);
CGContextMoveToPoint(c, 60, 60);
CGContextAddLineToPoint(c, 60, 250);
CGContextAddLineToPoint(c, 60, 249);
CGContextStrokePath(c);
CGContextSetStrokeColorWithColor(c, [UIColor blueColor].CGColor);
CGContextBeginPath(c);
CGContextMoveToPoint(c, 160, 60);
CGContextAddLineToPoint(c, 160, 250);
CGContextAddLineToPoint(c, 160.01, 249);
CGContextStrokePath(c);
}
这会生成以下输出:
红色形状的底边是否有圆角?或者,当这条线与自身完全相加时,它是Core Graphics中的一个错误吗?
答案 0 :(得分:4)
这绝对是个错误。如果您尝试在路径中添加另一行,则可以看到Core Graphics无法处理它。
CGContextMoveToPoint(c, 60.0, 60.0);
CGContextAddLineToPoint(c, 60.0, 250.0);
CGContextAddLineToPoint(c, 60.0, 249.0);
CGContextAddLineToPoint(c, 60.0, 250.0);
就好像创建圆角帽和连接的蒙版在加倍时会被反转。
答案 1 :(得分:3)
mortenfast证明这是一个错误。但是我会发布这个答案来提供我的解决方法。
解决方法是检测这种情况并添加一条与现有线垂直的非常短的线段,如下所示:
- (void)addPtToPath:(CGPoint)newPt {
// CoreGraphics seems to have a bug if a path doubles back on itself.
// Detect that and apply a workaround.
CGPoint curPt = CGPathGetCurrentPoint(self.currentPath);
if (!CGPointEqualToPoint(newPt, curPt)) {
CGFloat slope1 = (curPt.y - prevPt.y) / (curPt.x - prevPt.x);
CGFloat slope2 = (curPt.y - newPt.y) / (curPt.x - newPt.x);
CGFloat diff;
BOOL between;
if (isinf(slope1) && isinf(slope2)) {
// Special-case vertical lines
diff = 0;
between = ((prevPt.y < curPt.y) != (curPt.y < newPt.y));
} else {
diff = slope1 - slope2;
between = ((prevPt.x < curPt.x) != (curPt.x < newPt.x));
}
if (between && diff > -0.1 && diff < 0.1) {
//NSLog(@"Hack alert! (%g,%g) (%g,%g) (%g,%g) => %g %g => %g", prevPt.x, prevPt.y, curPt.x, curPt.y, newPt.x, newPt.y, slope1, slope2, diff);
if (isinf(slope1)) {
curPt.x += 0.1;
} else if (slope1 == 0) {
curPt.y += 0.1;
} else if (slope1 < -1 || slope1 > 1) {
curPt.x += 0.1; curPt.y -= 0.1 / slope1;
} else {
curPt.x -= 0.1 * slope1; curPt.y += 0.1;
}
CGPathAddLineToPoint(self.currentPath, NULL, curPt.x, curPt.y);
}
prevPt = curPt;
}
CGPathAddLineToPoint(self.currentPath, NULL, newPt.x, newPt.y);
}
这需要一个名为prevPt
的ivar,并在ivar currentPath
的路径上运行。