放大时使用 CGContextStrokePath() 绘制的 iOS 绘图出现滞后/崩溃
问题 I 的概要
一个在 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();
}
}
任何有关此问题的帮助将非常感激;我对这个真的束手无策......
谢谢, 亚历克斯
Rundown of Problem
I an iPad app with a UIImageView inside of a UIScrollView. I want the user to be able to draw on-top of the UIImageView by using a stylus and/or their finger.
I have it working well on the simulator, but it completely lags out (and sometimes crashes) on the iPad. The problem becomes far more evident when you try and dry while already zoomed-in on the UIScrollView; it becomes incredibly laggy (essentially freezes) and then crashes.
(Scrolling on the UIScrollView does not conflict with drawing, as it is set to require 2 fingers when drawing is active.)
The Code
Here are the relevant methods. These methods are all inside of the view which handles the drawing:
/**
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();
}
}
Any help with this issue would be greatly appreciated; I'm really at my wits end with this one...
Thanks,
Alex
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我最近开发了一个可以在图像上绘图的应用程序。我实现它的方法是创建另一个 UIView 层,然后在该视图上进行图形/gl 绘图。然后你可以将所有触摸事件移动到 gl 视图。我当前的实现没有任何性能问题,放大时不应更改。还要检查您的内存,您可能会泄漏。
看看下面的苹果代码:
GLPaint
I have recently developed an app that allows for drawing on images. The way I implemented it was to create another UIView layer and then do my graphics/gl drawing on that view. Then you can move all your touch events to the gl view. I haven't had any performance issues with my current implementation and it shouldn't be changed when zoomed in. Also check your memory, you may be leaking.
Take a look at the following apple code:
GLPaint
正如您所说,您正在使用手写笔或手指,那么在使用手写笔/手指时,您如何处理触摸事件,我的意思是说,当用户手里拿着手写笔时,会将手放在ipad屏幕上,然后然后尝试书写(就像我们在纸上书写一样),看看您的手写笔是否可以在这种情况下工作。
as you have said that you are using stylus or finger, So while using stylus/finger, how are you handling touch events, I mean to say that, when a user holding a stylus in his hand, will rest his hand on ipad screen and then try to write,(as we write on a paper) so whether your stylus work in this scenario.