iOS绘图与CGContextStrokePath()滞后/崩溃时,绘图放大



问题概要

我是一个iPad应用,在UIScrollView中有一个UIImageView。我希望用户能够通过使用触控笔和/或手指在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();
    }
} 

对这个问题的任何帮助都将非常感谢。对于这个问题,我真的束手无策了。

谢谢,亚历克斯

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

看一下下面的apple代码:

GLPaint

正如你所说,你使用的是手写笔或手指,所以当使用手写笔/手指时,你是如何处理触摸事件的,我的意思是说,当用户拿着手写笔时,他的手会放在ipad屏幕上,然后试着写字,(就像我们在纸上写字一样)所以你的手写笔是否在这种情况下工作。

最新更新