似乎无法摆脱UIBezierPath中的界限

时间:2013-07-17 04:17:26

标签: iphone ios core-graphics uibezierpath

好的,所以我需要一个圆角三角形。所以我所做的是使用类似于我在其他矢量绘图程序中使用的技术。绘制三角形并使用笔划创建圆角。工作就像一个魅力,直到我需要减少用于填充和描边UIBezierPath的颜色的alpha。由于某种原因,我不断得到这个插入轮廓与填充和描边颜色不同。不知何故,alpha值没有得到尊重。也许我在这里忽略了一些愚蠢的东西,但试着尽可能地我不能得到三角形都低于1的三角形。这就是我得到的: enter image description here

这是简单的代码:

    - (void)drawRect:(CGRect)rect
{
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint: CGPointMake(63.5, 10.5)];
    [path addLineToPoint: CGPointMake(4.72, 119.5)];
    [path addLineToPoint: CGPointMake(122.28, 119.5)];
    [path addLineToPoint: CGPointMake(63.5, 10.5)];
    [path closePath];
    path.miterLimit = 7;

    path.lineCapStyle = kCGLineCapRound;

    path.lineJoinStyle = kCGLineJoinRound;
    path.lineWidth = 8;

    UIColor *whiteAlph5 = [UIColor colorWithWhite:0.6 alpha:0.5];

    [whiteAlph5 setFill];
    [whiteAlph5 setStroke];


    [path fill];
    [path stroke];
}

我无法理解为什么这条线除了“ whiteAlpha5 ”之外的任何东西,如果这是我为填充和描边设置的唯一颜色。我想我可以画圆角三角形,将曲线添加到角落,但我只是好奇为什么会发生这种情况。谢谢提前......

2 个答案:

答案 0 :(得分:4)

如果您必须中风,请将您的电话改为[UIBezierPath stroke],如下所示:

[path fill];
[path strokeWithBlendMode:kCGBlendModeCopy alpha:1.0];

这应该达到你想要的效果(我认为 - 无法测试它)

这是一个猜测,但我认为你在这里看到的基本上是两层半透明白色,一个在另一个上面绘制。当三角形刚刚填满时,它就是你所期待的。当你描边时,它会绘制相同的颜色 - 但是它会在现有颜色的基础上添加它,而不是替换它,如果你之前在绘画程序或类似程序中完成了这个,你可能会想到这种效果。因此,在笔划和填充重叠的地方,你会得到比你更强的白色。只使用填充本身就可以解决这个问题,但可能无法获得你所追求的圆润效果。

如果您需要直观地展示我的意思,可以在Photoshop中执行此操作。创建一个黑色背景的新图像并在其上方创建一个新图层,设置为50%不透明度。在上面画一个白色正方形(由于不透明度,它将看起来是灰色的)。然后,在不更改图层的情况下,在其中绘制一条线。你不会看到这条线,因为它正在取代现有的颜色 - 这就是你期望在你的代码中发生的事情。然后,在其上方添加另一个图层,同时设置为50%不透明度。在这个图层上,通过正方形画一条线。你会看到这条线是一个更亮的灰色。这是附加的,两层上的白色重叠 - 代码正在创建的效果。

答案 1 :(得分:2)

该行是因为您的笔触和填充绘制到相同的像素。由于笔划和填充都是部分透明的,因此颜色会累积。

解决此问题的一种方法是创建一个概述圆角三角形的路径,并在不拖动的情况下填充它。

这是一个类别的界面,用于创建概述圆角多边形的路径:

@interface UIBezierPath (MyRoundedPolygon)

+ (UIBezierPath *)my_roundedPolygonWithSides:(int)sides center:(CGPoint)center
    vertexRadius:(CGFloat)vertexRadius cornerRadius:(CGFloat)cornerRadius
    rotationOffset:(CGFloat)rotationOffset;

@end

以下是实施:

@implementation UIBezierPath (MyRoundedPolygon)

static CGPoint vertexForPolygon(int sides, CGPoint center, CGFloat circumradius, CGFloat index) {
    CGFloat angle = index * 2 * M_PI / sides;
    return CGPointMake(center.x + circumradius * cosf(angle),
        center.y + circumradius * sinf(angle));
}

+ (UIBezierPath *)my_roundedPolygonWithSides:(int)sides center:(CGPoint)center
    vertexRadius:(CGFloat)vertexRadius cornerRadius:(CGFloat)cornerRadius
    rotationOffset:(CGFloat)rotationOffset
{
    CGFloat circumradius = vertexRadius + cornerRadius;
    CGPoint veryLastVertex = vertexForPolygon(sides, center, circumradius, rotationOffset - 1);
    CGPoint currentVertex = vertexForPolygon(sides, center, circumradius, rotationOffset);
    CGMutablePathRef cgpath = CGPathCreateMutable();
    CGPathMoveToPoint(cgpath, NULL, (veryLastVertex.x + currentVertex.x) / 2,
        (veryLastVertex.y + currentVertex.y) / 2);
    for (CGFloat i = 0; i < sides; ++i) {
        CGPoint nextVertex = vertexForPolygon(sides, center, circumradius,
            i + 1 + rotationOffset);
        CGPathAddArcToPoint(cgpath, NULL, currentVertex.x, currentVertex.y,
            nextVertex.x, nextVertex.y, cornerRadius);
        currentVertex = nextVertex;
    }
    CGPathCloseSubpath(cgpath);
    UIBezierPath *path = [self bezierPathWithCGPath:cgpath];
    CGPathRelease(cgpath);
    return path;
}

@end

以下是您使用它的方式:

@implementation MyView

- (void)drawRect:(CGRect)rect
{
    CGRect bounds = self.bounds;
    CGPoint center = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds));
    UIBezierPath *path = [UIBezierPath my_roundedPolygonWithSides:3 center:center
        vertexRadius:70 cornerRadius:8 rotationOffset:0.25];
    [[UIColor colorWithWhite:0.6 alpha:0.5] setFill];
    [path fill];
}

@end

这是结果:

rounded triangle

请注意,将rotationOffset设置为0.25会使三角形旋转四分之一圈。将其设置为零将为您提供一个右指向三角形。