0

CoreGraphics を学習しようとしていますが、奇妙な動作に遭遇しました。

私は長方形を描き、その中に与えられた量のダイヤモンドを描きます.形状は異なる塗りつぶし(空、塗りつぶし、ストライプ)で描くことができます.私の描画長方形関数は次のようになります:

- (void)drawRect:(CGRect)rect
{
    UIBezierPath* roundedRect = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:9.0];

    //don't draw where the round corners "cut" the rectangle
    [roundedRect addClip];

    //set a white background
    [[UIColor whiteColor] setFill];
    UIRectFill(self.bounds);

    //set a black frame
    [[UIColor darkGrayColor] setStroke];
    [roundedRect stroke];

    self.shade = STRIPED;
    self.color = [UIColor greenColor];
    self.number = 3;
    rectOffset = self.bounds.size.width / (self.number * 2);
    [self drawDiamondNumberOfTimes:self.number startOrigin:self.bounds.origin];
}

drawDiamondNumberOfTimes:startOrigin: は、シェイプが描画される長方形を計算し、ストロークを使用してダイヤモンドの境界を描画する再帰関数です。

- (void) drawDiamondNumberOfTimes:(int) p_times startOrigin:(CGPoint) p_origin
{
    if( p_times > 0)
    {
        CGRect drawArea;
        drawArea.origin = CGPointMake(p_origin.x + rectOffset-shapeSize.width/2,    self.bounds.size.height/4);
        drawArea.size = shapeSize;

        UIBezierPath *diamond = [[UIBezierPath alloc] init];
        [diamond moveToPoint:CGPointMake(drawArea.origin.x, drawArea.origin.y+ shapeSize.height/2)];
        [diamond addLineToPoint:CGPointMake(drawArea.origin.x+shapeSize.width/2, drawArea.origin.y)];
        [diamond addLineToPoint:CGPointMake(drawArea.origin.x+shapeSize.width, drawArea.origin.y+ shapeSize.height/2)];
        [diamond addLineToPoint:CGPointMake(drawArea.origin.x+shapeSize.width/2, drawArea.origin.y+ shapeSize.height)];
        [diamond closePath];

        [self.color setStroke];
        [diamond stroke];
        [self drawShadeOfDraw:diamond atRect:drawArea];

        drawArea.origin.x += rectOffset + shapeSize.width/2;
        [self drawDiamondNumberOfTimes:p_times-1 startOrigin:drawArea.origin ];
    }
}

drawShadeOfDraw:atRect: 奇妙な動作が発生する別の塗りつぶしを設定します。

空と塗りつぶしでは完璧に機能しますが、ストライプでは、[p_symbol addClip] と書くと、self.number が 2 または 3 に設定されていても、常に 1 つのダイヤモンドがストライプされます。[p_symbol addClip] がないと、正しい数のダイヤモンドが得られますもちろん、ストライプは四角形全体にあります。drawShadeOfDraw:atRect のコードは次のとおりです。

- (void)drawShadeOfDraw:(UIBezierPath*)p_symbol atRect:(CGRect)p_drawArea
{
    switch (self.shade)
    {
        case STRIPED:
        {
            [p_symbol addClip];
            for( int y = p_drawArea.origin.y; y < p_drawArea.origin.y+ p_drawArea.size.height; y+= 6)
            {  
                [p_symbol moveToPoint:CGPointMake(p_drawArea.origin.x, y)];
                [p_symbol addLineToPoint:CGPointMake(p_drawArea.origin.x+shapeSize.width, y)];
                [self.color setStroke];
                [p_symbol stroke];
            }
            break;
        }
        case SOLID:
        {
            [self.color setFill];
            [p_symbol fill];
            break;
        }
        default:
        {
            break;
        }
    }
}

ここにいくつかの画像があります:

これはaddClipでどのように見えるかです

そしてaddClipなし

私は何を間違っていますか?

4

1 に答える 1

4

クリップへの追加は半永久的です。クリッピング領域が「縮小」されると、それ自体を再度拡大することはできません。以前の状態に戻すことしかできません。これを行うには、CGContextSaveGState()コンテキスト状態 (クリッピングを含む) を設定する前に呼び出し、その状態で描画を行い、その後呼び出しCGContextRestoreGState()てコンテキスト状態を以前の状態に戻します。

したがって、コンテキスト状態を保存および復元するための呼び出しで 2 つのメソッドをまとめることをお勧めします。UIGraphicsGetCurrentContext()現在のコンテキストへの参照を取得するために使用します。

于 2013-03-22T05:11:30.933 に答える