web-dev-qa-db-ja.com

iOSは塗りつぶされた円を描く

ここのグラフィックプログラマーではないので、私はこれをつまずこうとしています。私は9つの塗りつぶされた円を描画しようとしています。それぞれ異なる色で、それぞれ白い境界線があります。 UIViewのフレームはCGRectMake(0,0,60,60)です。添付画像をご覧ください。

問題は、両側の境界に「平らな斑点」ができていることです。以下は私のコードです(UIViewサブクラスから):

- (void)drawRect:(CGRect)rect
{
    CGRect borderRect = CGRectMake(0.0, 0.0, 60.0, 60.0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
    CGContextSetRGBFillColor(context, colorRed, colorGreen, colorBlue, 1.0);
    CGContextSetLineWidth(context, 2.0);
    CGContextFillEllipseInRect (context, borderRect);
    CGContextStrokeEllipseInRect(context, borderRect);
    CGContextFillPath(context);
}

DrawRectでCGRectMake(0,0,56,56)に変更すると、上部と左側にのみフラットスポットが表示され、下部と右側が正常に表示されます。

誰も私がこれを修正する方法を提案できますか?境界線はUIViewによってクリップされているように見えますが、これについてあまり知らないので、修正方法がわかりません。

グラフィックの専門家からの提案に感謝します。

enter image description here

34

私は@AaronGoldenからの答えが好きです、ただ追加したかったです:

CGRect borderRect = CGRectInset(rect, 2, 2);

または、より良い:

CGFloat lineWidth = 2;
CGRect borderRect = CGRectInset(rect, lineWidth * 0.5, lineWidth * 0.5);
38
Wain

これらの円は、それらを描くビューの境界にクリップされています。ビューは、描かれる円よりわずかに大きくなければなりません。 CGContextStrokeEllipseInRect呼び出しが半径30の円をトレースし、トレースされた曲線の両側に1ピクセルずつペイントすることを想像できます。遠端では、これらのピクセルの1つをビューの境界のすぐ外側に配置します。

ビューを62x62のようにするか、円の半径をわずかに小さくして、60x60ビューで太いストロークの余地を残してください。

17
Aaron Golden

これを書いて、多くの円を簡単に描画できるようにしました。

.mファイルに次のコードを追加します。

- (void) circleFilledWithOutline:(UIView*)circleView fillColor:(UIColor*)fillColor outlineColor:(UIColor*)outlinecolor{
CAShapeLayer *circleLayer = [CAShapeLayer layer];
float width = circleView.frame.size.width;
float height = circleView.frame.size.height;
[circleLayer setBounds:CGRectMake(2.0f, 2.0f, width-2.0f, height-2.0f)];
[circleLayer setPosition:CGPointMake(width/2, height/2)];
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(2.0f, 2.0f, width-2.0f, height-2.0f)];
[circleLayer setPath:[path CGPath]];
[circleLayer setFillColor:fillColor.CGColor];
[circleLayer setStrokeColor:outlinecolor.CGColor];
[circleLayer setLineWidth:2.0f];
[[circleView layer] addSublayer:circleLayer];
}

次に、ロードしたビューに次のコードを追加し、「yourView」をサークルを配置するビューに置き換えます。たくさんのサークルを作成する場合は、ページにいくつかの小さなビューを追加して、以下のコードを繰り返します。円は、作成するビューのサイズになります。

[self circleFilledWithOutline:self.yourView fillColor:[UIColor redColor] outlineColor:[UIColor purpleColor]];
7
Trianna Brannon

塗りつぶし円を描く簡単な方法があります

CGContextFillEllipseInRect(context, CGRectMake(x,y,width,height))
6
王怡飞

Swiftに関するTrianna Brannonの回答

func circleFilledWithOutline(circleView: UIView, fillColor: UIColor, outlineColor:UIColor) {
    let circleLayer = CAShapeLayer()
    let width = Double(circleView.bounds.size.width);
    let height = Double(circleView.bounds.size.height);
    circleLayer.bounds = CGRect(x: 2.0, y: 2.0, width: width-2.0, height: height-2.0)
    circleLayer.position = CGPoint(x: width/2, y: height/2);
    let rect = CGRect(x: 2.0, y: 2.0, width: width-2.0, height: height-2.0)
    let path = UIBezierPath.init(ovalIn: rect)
    circleLayer.path = path.cgPath
    circleLayer.fillColor = fillColor.cgColor
    circleLayer.strokeColor = outlineColor.cgColor
    circleLayer.lineWidth = 2.0
    circleView.layer.addSublayer(circleLayer)
}

そして、以下を介してfuncを呼び出します。

self.circleFilledWithOutline(circleView: myCircleView, fillColor: UIColor.red, outlineColor: UIColor.blue)
4
user7205499