15

UIViewのdrawRectメソッドで、線の非常に細いヘアライン幅を描画したいと思います。CGContextSetLineWidthの値が0.5であることがわかる線は、境界線CALayerの描画に使用されるのと同じ1.0幅の値と一致しません。

2つの違いがわかります。赤い線(幅= 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

パスをストロークすると、ストロークがパスにまたがります。別の言い方をすれば、パスはストロークの中心に沿っています。

パスが2つのピクセル間のエッジに沿って走っている場合、ストロークはそのエッジの両側のピクセルを(部分的に)カバーします。線幅が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 に答える