CGContextSetLineWidth在路径周围变化的宽度

时间:2010-10-29 05:01:08

标签: iphone cocoa cocoa-touch core-graphics

在我的一个应用程序中,我有一个自定义绘制的半透明UIView,我将其用作另一个UIView顶部的封面以获得特殊效果。

低视图: alt text

自定义视图的下方视图位于顶部: alt text

它有效,它在iPhone上的边缘只有10个像素,但现在我需要扩展左右边距以匹配它下面的行。

这是我的代码:

- (void)draw:(TTStyleContext*)context {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextSaveGState(ctx);

    [_color setStroke];
    CGContextSetLineWidth(ctx, MIN(_xwidth, _ywidth));

    CGFloat fw = context.frame.size.width;
    CGFloat fh = context.frame.size.height;

    CGContextMoveToPoint(ctx, fw, floor(fh/2));
    CGContextAddArcToPoint(ctx, fw, fh, floor(fw/2), fh, RD(_radius));
    CGContextAddArcToPoint(ctx, 0, fh, 0, floor(fh/2), RD(_radius));
    CGContextAddArcToPoint(ctx, 0, 0, floor(fw/2), 0, RD(_radius));
    CGContextAddArcToPoint(ctx, fw, 0, fw, floor(fh/2), RD(_radius));
    CGContextClosePath(ctx);
    CGContextStrokePath(ctx);

    CGContextRestoreGState(ctx);

    context.frame = CGRectInset(context.frame, _xwidth/2, _ywidth/2);
    return [self.next draw:context];
}

设置_xwidth_ywidth后,此代码的关键部分是笔画宽度的MIN。这里的想法是框架默认情况下,周围的笔画宽度相同。我要求它做的是使两侧的行程宽度大于顶部和底部的行程宽度。使用MIN可确保笔划不会变得更粗_xwidth尺寸并渗入中心。如果我使用_ywidth值,侧面看起来很棒,但我不再透明红色,因为顶部和底部边框渗入中心。这让我想到了我的问题:

有没有办法让我指明我希望两侧的笔画粗_xwidth,顶部和底部的_ywidth厚?如果没有,还有另一种我更容易忽视的方式吗?

使用我的代码,_xwidth设置为42,_ywidth设置为10,我得到: alt text 你可以在这里看到我想要的东西,以及如何让侧面笔划覆盖未被覆盖的红色背景。

2 个答案:

答案 0 :(得分:0)

我能够通过改变路径并用更细的线条抚摸它来破解它,然后在扩展的矩形周围应用另一个笔划,用较粗的线来掩盖溢出

- (void)draw:(TTStyleContext*)context {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextSaveGState(ctx);

    CGRect oldFrame = context.frame;

    context.frame = CGRectInset(context.frame, (_xwidth > _ywidth ? _xwidth/2 : 0), (_ywidth > _xwidth ? _ywidth/2 : 0));
    CGFloat ox = (_xwidth > _ywidth ? _xwidth/2 - _ywidth/2 : 0);
    CGFloat oy = (_ywidth > _xwidth ? _ywidth/2 - _xwidth/2 : 0);
    CGFloat fw = context.frame.size.width + ox + (_xwidth > _ywidth ? _ywidth : 0);
    CGFloat fh = context.frame.size.height + oy + (_ywidth > _xwidth ? _xwidth : 0);

    CGContextMoveToPoint(ctx, fw, floor(fh/2));
    CGContextAddArcToPoint(ctx, fw, fh, floor(fw/2), fh, RD(_radius));
    CGContextAddArcToPoint(ctx, ox, fh, ox, floor(fh/2), RD(_radius));
    CGContextAddArcToPoint(ctx, ox, oy, floor(fw/2), oy, RD(_radius));
    CGContextAddArcToPoint(ctx, fw, oy, fw, floor(fh/2), RD(_radius));
    CGContextClosePath(ctx);

    [_color setStroke];
    CGContextSetLineWidth(ctx, MIN(_xwidth, _ywidth));
    CGContextStrokePath(ctx);

    if (_xwidth != _ywidth) {
        CGContextSetLineWidth(ctx, MAX(_xwidth, _ywidth));
        CGContextStrokeRect(ctx, CGRectInset(oldFrame, (_ywidth > _xwidth ? -2*_xwidth : 0), (_xwidth > _ywidth ? -2*_ywidth : 0)));
    }

    CGContextRestoreGState(ctx);

    context.frame = CGRectInset(oldFrame, _xwidth/2, _ywidth/2);
    return [self.next draw:context];
}

alt text

答案 1 :(得分:0)

简单地填充你正在抚摸的相同路径会简单得多。