使用CGContext进行iOS绘图Stroke Path()在放大时绘制时滞后/崩溃

时间:2011-07-27 19:48:49

标签: ios ios4 uiscrollview quartz-2d cgcontext

问题的破坏

我是一个在UIScrollView内部带有UIImageView的iPad应用程序。我希望用户能够使用手写笔和/或他们的手指在UIImageView上绘制。

我在模拟器上运行良好,但它在iPad上完全滞后(有时会崩溃)。当你尝试在UIScrollView上干掉同时已经放大时,问题变得更加明显;它变得非常迟钝(基本上是冻结)然后崩溃。

(在UIScrollView上滚动与绘图不冲突,因为在绘图处于活动状态时设置为需要2个手指。)

守则

以下是相关方法。这些方法都在处理绘图的视图中:

 /**
 When the user first starts writing
 */
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    isMouseMoved = NO;
    UITouch *touch = [touches anyObject]; 

    CGPoint currentPoint = [touch locationInView:imageView];

    if(isEraserOn){
        [self changeEraserLocationTo:currentPoint];
    } 

    [self resetEraser:FALSE];
    lastPoint = [touch locationInView:imageView];
} 

/**
 When the user first starts moving the pen
 */
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    isMouseMoved = YES; 
    UITouch *touch = [touches anyObject]; 
    CGPoint currentPoint = [touch locationInView:imageView]; 

    // Setting up the context
    UIGraphicsBeginImageContext(imageView.frame.size);
    [imageView.image drawInRect:CGRectMake(0, 0, imageView.frame.size.width, imageView.frame.size.height)];

    if (isEraserOn) {
        CGContextSetLineWidth(UIGraphicsGetCurrentContext(), eraserRadius);
        CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);
        CGRect eraserFrame = eraser.frame; 
        eraserFrame.origin.x = currentPoint.x - (eraserRadius/2);
        eraserFrame.origin.y = currentPoint.y - (eraserRadius/2);
        eraser.frame = eraserFrame;
    } else {
        CGContextSetLineWidth(UIGraphicsGetCurrentContext(), penRadius);
        CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), r, g, b, 1.0); 
        CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeNormal);
    }

    CGContextBeginPath(UIGraphicsGetCurrentContext());
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
    CGContextStrokePath(UIGraphicsGetCurrentContext());

    imageView.image = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    lastPoint = currentPoint; 
    mouseMoved++; 

    if (mouseMoved == 1) {
        mouseMoved = 0;
    } 
} 

/**
 When the user stops writing
 */
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
    [self resetEraser:TRUE]; 

    if (!isMouseMoved) {
        UIGraphicsBeginImageContext(imageView.frame.size);
        CGContextRef contextRef = UIGraphicsGetCurrentContext(); 

        [imageView.image drawInRect:CGRectMake(0, 0, imageView.frame.size.width, imageView.frame.size.height)];

        CGContextSetLineWidth(contextRef, penRadius);
        CGContextSetRGBStrokeColor(contextRef, r, g, b, 1.0);
        CGContextMoveToPoint(contextRef, lastPoint.x, lastPoint.y);
        CGContextAddLineToPoint(contextRef, lastPoint.x, lastPoint.y);
        CGContextStrokePath(contextRef);
        imageView.image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }
} 

对此问题的任何帮助都非常赞赏;我真的很想知道这个......

谢谢, 亚历

2 个答案:

答案 0 :(得分:1)

我最近开发了一款可以在图像上绘图的应用程序。我实现它的方法是创建另一个UIView层,然后在该视图上执行我的graphics / gl绘图。然后,您可以将所有触摸事件移动到gl视图。我的当前实现没有任何性能问题,放大时不应该更改。还要检查你的内存,你可能会泄漏。

查看以下苹果代码:

GLPaint

答案 1 :(得分:0)

正如你所说的那样你正在使用手写笔或手指,所以在使用手写笔/手指时,你是如何处理触摸事件的,我的意思是说,当用户手里拿着手写笔时,会把手放在手上ipad屏幕,然后尝试写,(因为我们写在纸上)所以你的手写笔是否适用于这种情况。