【问题标题】:How to change a Shape of UIBezierPath Drawing line?如何更改 UIBezierPath 绘图线的形状?
【发布时间】:2016-01-27 06:01:40
【问题描述】:

有什么方法可以改变 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);
    }

【问题讨论】:

  • 好的,我会看到兄弟@HarvantS。
  • @HarvantS。我已经编辑了我的问题,请检查它,只有我需要更改结构,我是绘图应用程序的新手,如果可能的话我需要更多参考,请告诉我我会做的。
  • @HarvantS。在这里发布您的答案,因为我需要解释它是如何发生的,我是绘图应用程序的新手,所以请帮助我
  • 是的,你可以这样做。您需要有自定义形状的图标。

标签: ios objective-c calayer uibezierpath


【解决方案1】:

是的,它是可行的,但它不是微不足道的。您本质上想要的是用星星而不是普通的破折号来描边。据我所知,iOS 只提供了一个标准方法的 API,即用矩形虚线图案描边。

如果你想实现自定义描边,你必须自己做。您可能必须先展平贝塞尔路径。然后沿着路径“走”,并以一定的间隔手动绘制星星/圆圈/松鼠。如果您需要星星之间的间隔相等,则尤其困难。

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

DrawKit 在NSBezierPath 类上有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 让你感到迷惑,网上可能有 iOS 的开源绘图库,尝试搜索它们,看看自定义绘图是如何完成的。

【讨论】:

  • 所以没有内置选项@euvs 正确,我们需要为它进行定制设计。
  • AFAIK 如果没有 Core-Graphics,您将无法做到。我问题中的代码几乎包含您想要的一切。我对那个代码做了同样的事情。你只需要一个“明星”形象。将其作为模式传递(在回调中),它将为您绘制该图像作为路径。
  • @HarvantS。 CGContextSetFillPattern 函数是否会沿着路径跟随并以相等的间隔沿着路径放置星星?还是将星星放置在 x,y 轴上对齐的网格状图案中,然后将路径用作遮罩以仅显示一些星星?
  • 它将填充边框中的图案(与简单颜色相同)。看起来你正在用铅笔或粉笔画画。 thumbs.dreamstime.com/z/… 类似这样的东西。如果 OP 需要两颗星之间的间隔相等,他必须微调算法。
【解决方案2】:

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

您可以试试 RobMayoff here: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];
        }  
    }

最后是draw rect方法:

   - (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;

【讨论】:

  • 先生,我必须在 uiimage 自定义类或 uiview 自定义类中提供此方法
【解决方案3】:

我只是使用 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 框架。

我希望它对某些人有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-08
    • 2011-05-04
    • 1970-01-01
    • 1970-01-01
    • 2013-10-08
    • 2012-07-24
    • 1970-01-01
    相关资源
    最近更新 更多