15

我想在 UIView 的 drawRect 方法中绘制一条非常细的细线宽度。我看到的 CGContextSetLineWidth 值为 0.5 的线与用于绘制边框 CALayer 的 1.0 宽度值不匹配。

您可以看到两者之间的区别 - 红线(宽度 = 1)比紫/蓝线(宽度 = 0.5)细得多。

用CALayer绘制的边框

这是我绘制伪 1.0 宽度水平线的方式:

CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(ctx, [UIColor blueColor].CGColor);
CGContextSetLineWidth(ctx, 0.5); // I expected a very thin line

CGContextMoveToPoint(ctx, 0, y);
CGContextAddLineToPoint(ctx, self.bounds.size.width, y);

CGContextStrokePath(ctx);

这是同一视图的边框,这次使用 1.0 边框宽度:

UIView *myView = (UIView *)self;
CALayer *layer = myView.layer;
layer.borderColor = [UIColor redColor].CGColor;
layer.borderWidth = 1.0;

我需要做些什么来绘制我自己的与 CALayer 版本宽度相同的自定义线?

4

2 回答 2

38

描边路径时,描边跨越路径。换句话说,路径位于笔画的中心。

如果路径沿着两个像素之间的边缘延伸,则笔划将(部分)覆盖该边缘两侧的像素。线宽为 0.5 时,水平笔划将延伸 0.25 点进入路径上方的像素,并延伸 0.25 点进入路径下方的像素。

您需要移动路径,使其不会沿着像素边缘运行:

CGFloat lineWidth = 0.5f;
CGContextSetLineWidth(ctx, lineWidth);

// Move the path down by half of the line width so it doesn't straddle pixels.
CGContextMoveToPoint(ctx, 0, y + lineWidth * 0.5f);
CGContextAddLineToPoint(ctx, self.bounds.size.width, y + lineWidth * 0.5f);

但由于您只是绘制一条水平线,因此使用起来更简单CGContextFillRect

CGContextSetFillColorWithColor(ctx, [UIColor blueColor].CGColor);
CGContextFillRect(ctx, CGRectMake(0, y, self.bounds.size.width, 0.5f));
于 2012-10-14T03:08:35.617 回答
16

当未在积分上绘制时,您需要关闭抗锯齿以获得细线。

CGContextSetShouldAntialias(ctx, NO)
于 2013-06-19T20:10:26.123 回答