如何更改 UIBezierPath 绘图线的形状?

How to change a Shape of UIBezierPath Drawing line?

有什么方法可以改变 UIBezierPath 的绘图形状吗,请看下图,当用户拖动手指时它像一条线,但我想要星号、圆圈和其他有什么方法可以实现。

我的期望是

这是我的 UIBezierPath 代码:

-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        UITouch *touch = [[event allTouches] anyObject];
        touchPoint = [touch locationInView:self];

        if (!CGPointEqualToPoint(startingPoint, CGPointZero))
        {
            UIBezierPath *path = [UIBezierPath bezierPath];
            [path moveToPoint:CGPointMake(touchPoint.x,touchPoint.y)];
            [path addLineToPoint:CGPointMake(startingPoint.x,startingPoint.y)];

            CAShapeLayer *shapeLayer = [CAShapeLayer layer];
            shapeLayer.path = [path CGPath];
            shapeLayer.strokeColor = [single.arrColor[single.i] CGColor];
            if([UIDevice currentDevice].userInterfaceIdiom ==UIUserInterfaceIdiomPad)
            {
                shapeLayer.lineWidth = 7.0;

            }
            else
            {
                shapeLayer.lineWidth = 5.0;

            }
            shapeLayer.fillColor = [[UIColor redColor] CGColor];
            [self.layer addSublayer:shapeLayer];
            [clearBeizer addObject:shapeLayer];
        }
        startingPoint=touchPoint;
        //    [arrLayer addObject:shapeLayer];
        NSLog(@"Touch moving point =x : %f Touch moving point =y : %f", touchPoint.x, touchPoint.y);
    }

是的,这是可行的,但并非微不足道。您本质上想要的是用星号而不是普通的破折号划出一条路径。据我所知,iOS 只提供了一个 API 的标准方法,即用矩形破折号图案抚摸。

如果你想实现自定义描边,你必须自己做。您可能必须首先展平贝塞尔曲线路径。然后"walk"沿路径手动绘制stars/circle/squirrels一定间隔。如果您需要星星之间的间隔相等,这尤其困难。

您可以查看 DrawKit MacOS 库。 DrawKit 适用于 MacOS,而非 iOS!这只是您了解想法的参考。

DrawKit 在 NSBezierPath class 上有 NSBezierPath+Geometry.h 个类别。您可以从 (NSBezierPath*)bezierPathWithZig:(CGFloat)zig zag:(CGFloat)zag 方法开始,看看 zig-zagy 路径是如何实现的

https://github.com/DrawKit/DrawKit/.../NSBezierPath-Geometry.m#L1206

或波浪形路径[(NSBezierPath*)bezierPathWithWavelength:amplitude:spread:]

https://github.com/DrawKit/DrawKit/..../NSBezierPath-Geometry.m#L1270

仅供参考:UIBezierPath (iOS) 通常缺少 NSBezierPath (MacOS) 中可用的方法

如果 DrawKit 让您感到困惑,Internet 上可能有 open-sourced 个用于 iOS 的绘图库,尝试搜索它们,看看自定义绘图是如何完成的。

是的,你可以做到。但是您必须为此任务获取自定义形状的图标。

您可以试试 RobMayoff 提供的这个优秀答案 here: and the git repo

这是另一种方法:

我制作了一个简单的图像编辑应用程序,类似于您正在做的。

你可以在图片上画心形:

这样,您可以绘制许多自定义形状:

代码非常简单明了:

您需要创建一些自定义形状的橡皮擦。我称他们为橡皮擦,因为他们只是擦掉照片 :P .

自定义橡皮擦的方法如下:

- (void)newMaskWithColor:(UIColor *)color eraseSpeed:(CGFloat)speed {
    wipingInProgress = NO;
    eraseSpeed = speed;  //how fast eraser should move
    maskColor = color; //eraser color
    [self setNeedsDisplay];
}
-(void)setErase:(UIImage *)img{
eraser =img; //set the custom shaped image here
} 

并在视图上绘制自定义形状的橡皮擦:

   - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
        wipingInProgress = YES;
    }
   - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
        if ([touches count] == 1) {
            UITouch *touch = [touches anyObject];
            location = [touch locationInView:self];
            location.x -= [eraser size].width/2;
            location.y -= [eraser size].width/2;
            [self setNeedsDisplay];
        }  
    }

最后绘制矩形方法:

   - (void)drawRect:(CGRect)rect {

    CGContextRef context = UIGraphicsGetCurrentContext();
    if (wipingInProgress) {
        if (imageRef) {
            // Restore the screen that was previously saved
            CGContextTranslateCTM(context, 0, rect.size.height);
            CGContextScaleCTM(context, 1.0, -1.0);

            CGContextDrawImage(context, rect, imageRef);
            CGImageRelease(imageRef);

            CGContextTranslateCTM(context, 0, rect.size.height);
            CGContextScaleCTM(context, 1.0, -1.0);
        }

        [eraser drawAtPoint:location blendMode:kCGBlendModeDestinationOut alpha:eraseSpeed];
    }
    // Save the screen to restore next time around
    imageRef = CGBitmapContextCreateImage(context);

}

以下是 .h 文件中声明的一些变量:

CGPoint     location;
CGImageRef  imageRef;
UIImage     *eraser;
BOOL        wipingInProgress;
UIColor     *maskColor;
CGFloat     eraseSpeed;

我只是使用 UIImageView 完成了此操作:

 UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:single.arrimages[single.colorimages]]];
                imageView.frame = CGRectMake(touchPoint.x, touchPoint.y, 30,30);
                [self addSubview:imageView];

只需在用户触摸屏幕时添加图像。

获取用户触摸的x,y坐标并将其提供给uiimageview框架。

希望对大家有所帮助。