如何更改 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框架。
希望对大家有所帮助。
有什么方法可以改变 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框架。
希望对大家有所帮助。