【问题标题】:Fill UIBezierPath填充 UIBezierPath
【发布时间】:2012-09-05 10:20:45
【问题描述】:

我正在尝试动态创建拼图,它看起来像这样:

我想用一些颜色填充这个形状,使它看起来像这样:

所以我可以用它来掩盖一些图像。
问题: 我用 4 个 UIBezierPath 创建了这个形状,然后使用 appendPath 将其转换为 1 个路径。
我想填充这条路径,但是当我使用 fill 时,我得到了这个:

您知道如何填充相同的形状吗?

【问题讨论】:

    标签: iphone ios ipad quartz-2d


    【解决方案1】:

    一段时间后,我找到了获得这些结果的原因。 如果要创建填充路径,则不应使用moveToPoint 方法,而应使用moveToPoint 设置第一个点,然后使用addLineToPointaddCurveToPoint 等绘制所有线条。

    完成绘制路径后,不要忘记发送closePath 消息。

    在我知道这一点之前,我使用不同的 UIBezierPath 实例绘制了拼图的每一面,并使用moveToPoint为每条路径设置了第一个点。

    【讨论】:

    • 我遇到了同样的问题,但我认为您的解决方案不会奏效。以拼图块为例,右边缘和下边缘是使用基本相同的三次贝塞尔曲线创建的,第二个只是另一个的 CGAffineTransform。即使没有在第二条曲线上使用 moveToPoint,变换似乎也阻止了两条曲线连接,因此填充的范围只是定义每条边的曲线。如果有人对此有解决方案,仍然可以使用转换,请分享。
    • @Victor Engel,我的解决方案正在运行,我在我的应用程序中使用它。为什么你谈论 CGAffineTransform?我不是用它来画拼图线。所有贝塞尔线都是使用为每条贝塞尔曲线计算的坐标绘制的。
    • 我并不是要暗示这是你的问题。我用你的插图来说明一个并发症。你们很多人不使用变换,但可以使用变换将一个变换到另一个,而无需计算出其他坐标。我认为我的解决方案是将转换应用于 CGPoints,以便不需要转换路径。然后我可以将它们全部添加到一个路径中。
    • 我相信closePath 是不需要的,它是隐式调用的。
    • @zakhej 嘿,伙计!感谢分享,你为我节省了几个小时:D
    【解决方案2】:

    如果你有一个定义你的拼图的路径,如果你把它变成CAShapeLayer,操作起来会更容易:

    CAShapeLayer *myShapeLayer = [CAShapeLayer layer];
    myShapeLayer.path = myBezierCurves.CGPath;
    myShapeLayer.fillColor = [[UIColor blackColor] CGColor];
    
    myShapeLayer.strokeColor = [[UIColor redColor] CGColor];
    myShapeLayer.lineWidth = 2;
    

    【讨论】:

    • 谢谢你的建议,我得到了这个:not filled image 并且它没有填充......
    • 我找到了原因,请看我的回答。
    【解决方案3】:

    试试这个:打算用所有组合点制作一个 UIbenzierPath

    在 .m 文件中添加以下方法。

     void MyCGPathApplierFunc (void *info, const CGPathElement *element) {
    
    UIBezierPath *drawingPath = (UIBezierPath *)info;
    CGPoint *points = element->points;
    CGPathElementType type = element->type;
    
    switch(type) {
        case kCGPathElementMoveToPoint: // contains 1 point
            [drawingPath moveToPoint:[[NSValue valueWithCGPoint:points[0]] CGPointValue]];
            break;
    
        case kCGPathElementAddLineToPoint: // contains 1 point
            [drawingPath addLineToPoint:[[NSValue valueWithCGPoint:points[0]] CGPointValue]];
            break;
        case kCGPathElementAddQuadCurveToPoint: // contains 1 point
            [drawingPath addQuadCurveToPoint:[[NSValue valueWithCGPoint:points[0]] CGPointValue]];
            break;
    
       case kCGPathElementAddCurveToPoint: // contains 1 point
            [drawingPath addCurveToPoint:[[NSValue valueWithCGPoint:points[0]] CGPointValue]];
            break;
    
        case kCGPathElementCloseSubpath: // contains no point
            break;
    }
    }
    

    添加 UIBezierPath *combinedpath;在 .h 文件中你可以使用如下方法:

    combinedpath = [[UIBezierPath alloc]init];
    CGPathApply(appendedBenzierPath.CGPath, (void *)combinedpath, MyCGPathApplierFunc);
    [self setNeedsDisplay];
    

    现在填写这些组合路径

    - (void)drawRect:(CGRect)rect
    {
      [[UIColor blackColor] setStroke];
      [combinedpath strokeWithBlendMode:kCGBlendModeNormal alpha:1.0];
      [combinedpath fill];
    }
    

    【讨论】:

    • XCode 表示"Instance method '-addQuadCurveToPoint' not found",与“MyCGPathApplierFunc”函数中的 addCurveToPoint 相同。所以我在运行时出错"-[UIBezierPath addCurveToPoint:]: unrecognized selector sent to instance"
    • 删除那个案例 :kCGPathElementAddCurveToPoint 并继续
    • 现在它什么也没画。空白屏幕。
    • 当我实现drawRect 方法时,我只看到黑屏。并且没有绘制任何东西。
    • 我找到了原因,请看我的回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多