在 UIView 上涂鸦 - ios 开发

Posted

技术标签:

【中文标题】在 UIView 上涂鸦 - ios 开发【英文标题】:doodle on UIView - ios development 【发布时间】:2012-03-28 19:40:36 【问题描述】:

您好,我正在开发这个项目以允许用户在 UIView 上涂鸦。我的方法是创建一个 CGMutablePathRef 路径并在 TouchMoved 时向其中添加新行。

相关代码如下,属于UIView类。

static CGMutablePathRef path; //create it as static value. 
//I got this habit from java coding but actually not sure 
//if it's a good way to do it in objective-c.


//draw the path

-(void)drawRect:(CGRect)rect
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextBeginPath(context);
    CGContextAddPath(context, path);
    CGContextStrokePath(context);
    CGPathRelease(path);


//touch began. create the path and add point.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

    path = CGPathCreateMutable();
    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView:self];
    CGPathMoveToPoint(path, NULL, point.x, point.y);
    [self setNeedsDisplay];            



//add points when touch moved
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView:self];

    CGPathAddLineToPoint(path, NULL, point.x, point.y);
    [self setNeedsDisplay];



//last points when touch ends
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView:self];
    CGPathAddLineToPoint(path, NULL, point.x, point.y);
    [self setNeedsDisplay];

但是,我遇到了错误,我并没有真正理解它们......我猜这是 UIGestureRecognizer 的问题,我从其他涂鸦代码中看到了它。是否需要添加 UIGestureRecognizer ?我还没有学到任何东西,所以我试图避免使用它。但如果必须的话,我会试一试。

我正在考虑的另一种方法是将所有点位置存储到一个可变数组中,因为我必须将这些点位置值存储在某个地方。但是,我不知道数组是否合适,因为我还没有找到将浮点值存储到数组的方法。如果有人可以帮助我,这将非常有帮助。谢谢!

【问题讨论】:

无需使用 UIGestureRecognizers。至于将浮点数存储到 NSMutableArray,请查看[NSNumber numberWithFloat:]。也看看这个问题:***.com/questions/7393058/… 我建议使用手势识别器。它使您的代码更简单,更易于扩展。 @rokjarc 是的,链接的问题非常有帮助。还有一个小问题:该答案中使用的类是 UIImageView,因此在它调用的方法中 [self.image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)]。但在我的情况下它是 UIView,那么我应该调用什么方法来绘制呢? (对不起,我猜这是一个愚蠢的问题。我真的是一个新手。)谢谢! 【参考方案1】:

感谢为我提供帮助的人。在看了一堆代码和方法之后,幸运的是我找到了解决这个问题的有效方法!

一般来说,我的 SketchView 中的 imageView 会在我绘图时动态更新。也就是每多画一个像素,就会在那个新像素上加一行,改变UIImageView,然后设置为UIView的背景图。

SketchView.h

@property (assign, nonatomic) CGPoint CurrentPoint;
@property (assign, nonatomic) CGPoint PreviousPoint;
@property (assign, nonatomic) CGPoint InitialPoint;

SketchView.m

@synthesize CurrentPoint;
@synthesize PreviousPoint;
@synthesize InitialPoint;


//begin the touch. store the initial point because I want to connect it to the last   
//touch point
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView:image];
    InitialPoint = point;

    


//When touch is moving, draw the image dynamically
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

UITouch *touch = [touches anyObject];
PreviousPoint = [touch previousLocationInView:image];
CurrentPoint = [touch locationInView:image];
UIGraphicsBeginImageContext(image.frame.size); 
CGContextRef ctx = UIGraphicsGetCurrentContext();   
[image.image drawInRect:CGRectMake(0, 0, image.frame.size.width,   image.frame.size.height)];
CGContextSetLineCap(ctx, kCGLineCapRound);
CGContextSetLineWidth(ctx, 5.0);
CGContextSetRGBStrokeColor(ctx, 1.0, 0.0, 0.0, 1.0);
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, PreviousPoint.x, PreviousPoint.y);
CGContextAddLineToPoint(ctx, CurrentPoint.x, CurrentPoint.y);
CGContextStrokePath(ctx);
image.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();




- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

UITouch *touch = [touches anyObject];
PreviousPoint = [touch previousLocationInView:image];
CurrentPoint = [touch locationInView:image];
UIGraphicsBeginImageContext(image.frame.size); 
CGContextRef ctx = UIGraphicsGetCurrentContext();
[image.image drawInRect:CGRectMake(0, 0, image.frame.size.width, image.frame.size.height)];
CGContextSetLineCap(ctx, kCGLineCapRound);
CGContextSetLineWidth(ctx, 5.0);
CGContextSetRGBStrokeColor(ctx, 1.0, 0.0, 0.0, 1.0);
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, PreviousPoint.x, PreviousPoint.y);
CGContextAddLineToPoint(ctx, CurrentPoint.x, CurrentPoint.y);

//I connected the last point to initial point to make a closed region
CGContextMoveToPoint(ctx, CurrentPoint.x, CurrentPoint.y);
CGContextAddLineToPoint(ctx, InitialPoint.x, InitialPoint.y);
CGContextStrokePath(ctx);
image.image = UIGraphicsGetImageFromCurrentImageContext();


UIGraphicsEndImageContext();

而且它有效!

附言我找到了

 PreviousPoint = [touch previousLocationInView:image];

非常有帮助,虽然在我发现涂鸦的代码中没有提到太多......我希望这会有所帮助。 :)

【讨论】:

以上是关于在 UIView 上涂鸦 - ios 开发的主要内容,如果未能解决你的问题,请参考以下文章

涂鸦蓝牙SDK开发系列教程——3.环境搭建

涂鸦Zigbee SDK开发系列教程——3.快速入门

iOS之UI--涂鸦画板实例

iOS开发Quartz2D 十三:画板涂鸦

涂鸦蓝牙SDK开发系列教程——1.快速入门

涂鸦蓝牙SDK开发系列教程——5.应用开发