在ios7中绘图时出现延迟
Posted
技术标签:
【中文标题】在ios7中绘图时出现延迟【英文标题】:Lag while drawing in ios7 【发布时间】:2013-10-01 04:46:06 【问题描述】:我有一个应用程序,我正在其中对视图进行一些草图绘制。
到目前为止,它运行良好,直到我安装了 ios7
。
我的应用程序使用 touchesmoved 方法来识别动作的变化。但是当我画一条线时,会调用 touches 方法,但直到我 touch 以 ios7
结束时,线才会更新。
所以画图有一点滞后。
它在ios6
和ios7
模拟器上运行良好,但是当我在真实的ios7
设备上测试它时,绘图算法存在延迟。
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
if (!isImageSelection)
mouseSwiped = NO;
UITouch *touch = [touches anyObject];
if ( [touch view] != baseview)
lastPoint2 = [touch locationInView:self.viewDrawing2];
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
if (!isImageSelection)
// NSLog(@"in image selection==%d touch moved ",isImageSelection );
mouseSwiped = YES;
UITouch *touch = [touches anyObject];
// if (([touch view] != btnInkColor) || ([touch view] != btnPenSize) || ([touch view] != baseview))
if ( [touch view] != baseview)
CGPoint currentPoint = [touch locationInView:self.viewDrawing];
if(isEraser)
// [[NSUserDefaults standardUserDefaults] floatForKey:@"strokeValue"];
UIGraphicsBeginImageContext(self.viewDrawing.frame.size);
[imgDrawing.image drawInRect:CGRectMake(0, 0, self.viewDrawing.frame.size.width, self.viewDrawing.frame.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), stroke);
//uncommented by prerak
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red, green, blue, 1.0);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
imgDrawing.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
else
float strokeT= [[NSUserDefaults standardUserDefaults] floatForKey:@"strokeValue"];
// NSLog(@"strokeT=%f",strokeT);
UIGraphicsBeginImageContext(self.viewDrawing.frame.size);
[imgDrawing.image drawInRect:CGRectMake(0, 0, self.viewDrawing.frame.size.width, self.viewDrawing.frame.size.height)];
// NSLog(@"STROKE %f",stroke);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), strokeT);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeCopy);
float redT=[[NSUserDefaults standardUserDefaults] floatForKey:@"redvalue"];
float greenT= [[NSUserDefaults standardUserDefaults] floatForKey:@"greenvalue"];
float blueT= [[NSUserDefaults standardUserDefaults] floatForKey:@"bluevalue"];
// NSLog(@"red=%f",redT);
// NSLog(@"green=%f",greenT);
// NSLog(@"blue=%f",blueT);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), redT, greenT, blueT, 1.0);
CGContextSetRGBFillColor(UIGraphicsGetCurrentContext(), redT, greenT, blueT, 1.0);
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineJoin(UIGraphicsGetCurrentContext(), kCGLineJoinRound);
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
imgDrawing.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lastPoint = currentPoint;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
UITouch *touch = [touches anyObject];
//if (([touch view] != btnInkColor) || ([touch view] != btnPenSize) || ([touch view] != baseview))
if ( [touch view] != baseview)
if (!isImageSelection)
if(!mouseSwiped)
if (isEraser)
UIGraphicsBeginImageContext(self.viewDrawing.frame.size);
[imgDrawing.image drawInRect:CGRectMake(0, 0, self.viewDrawing.frame.size.width, self.viewDrawing.frame.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), stroke);
// CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red, green, blue, 1.0);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
CGContextFlush(UIGraphicsGetCurrentContext());
imgDrawing.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
else
UIGraphicsBeginImageContext(self.viewDrawing.frame.size);
[imgDrawing.image drawInRect:CGRectMake(0, 0, self.viewDrawing.frame.size.width, self.viewDrawing.frame.size.height)];
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), stroke);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeCopy);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red, green, blue, 1.0);
CGContextSetRGBFillColor(UIGraphicsGetCurrentContext(), red, green, blue, 1.0);
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineJoin(UIGraphicsGetCurrentContext(), kCGLineJoinRound);
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
CGContextFlush(UIGraphicsGetCurrentContext());
imgDrawing.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
我该如何解决这个问题?
【问题讨论】:
我不知道你是怎么得到这个想法的。但是绘图代码应该在 drawRect 方法中而不是在 touch 方法中。 通过使用 CGMutablePathRef ,我解决了上述问题。 你能通过我上面的一些代码来展示这个吗?感谢您的回复。 【参考方案1】:要找到即时解决方案,请替换此行
mainImage.image = UIGraphicsGetImageFromContext(UIGraphicsGetCurrentContext());
与
[mainImage performSelectorInBackground:@selector(setImage:) withObject:UIGraphicsGetImageFromCurrentImageContext()];
如果您需要详细而准确的解决方案,请尝试将 MoveTo 替换为 CGMutablepath 。 希望这会有所帮助。
【讨论】:
【参考方案2】:我们已经在touchMoved
方法中使用dispatch_async(dispatch_get_main_queue(), ^);
块解决了这个问题,如下所示:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
dispatch_async(dispatch_get_main_queue(), ^
mouseSwiped = YES;
UITouch *touch = [touches anyObject];
if(touch.view==self.vwSwipePage)
return;
if(flagIsEraser)
CGPoint currentPoint;
if(flagActiveViewPage)
currentPoint = [touch locationInView:self.mainImage];
UIGraphicsBeginImageContext(self.mainImage.frame.size);
[self.mainImage.image drawInRect:CGRectMake(0, 0, self.mainImage.frame.size.width, self.mainImage.frame.size.height)];
else
currentPoint = [touch locationInView:self.mainImage1];
UIGraphicsBeginImageContext(self.mainImage1.frame.size);
[self.mainImage1.image drawInRect:CGRectMake(0, 0, self.mainImage1.frame.size.width, self.mainImage1.frame.size.height)];
//clear using circle brush........
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetLineWidth(context,20);
CGContextSetBlendMode(context, kCGBlendModeClear);
CGContextSetStrokeColorWithColor(context, [[UIColor clearColor] CGColor]);
CGContextBeginPath(context);
CGContextMoveToPoint(context, lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(context, currentPoint.x, currentPoint.y);
CGContextStrokePath(context);
CGContextFlush(context);
if(flagActiveViewPage)
self.mainImage.image = UIGraphicsGetImageFromCurrentImageContext();
else
self.mainImage1.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lastPoint = currentPoint;
);
愿这将帮助您解决您的问题。
谢谢
【讨论】:
好的,我会试着告诉你。感谢您的回复。 非常感谢,这对您有所帮助,但如果您更换技术员提到的那条线,那就完美了。 +1 为您提供帮助。 我也检查了使用技术员提到的这条线,真的它对我也很好......谢谢技术员 我之前提到过的方法可以正常工作,但是在使用 AddQuadCurveToPoint 时它只显示线条而不是平滑线条..所以这是完美的..再次感谢技术人员...【参考方案3】:这里列出了在 ios7 上存在相同问题的相同代码 https://***.com/questions/18198129/ios-7-making-my-apps-drawing-algorithm-lag 人们建议将绘图逻辑移到 drawRect 中:
【讨论】:
但是你能建议如何把这段代码放在draw rect方法中吗? 我现在自己也在寻找答案 :) 我会尽快发布它以上是关于在ios7中绘图时出现延迟的主要内容,如果未能解决你的问题,请参考以下文章
在异步 HTTP 请求的 completionHandler 中更新视图时出现延迟
想要在 jUnit 测试中访问延迟加载的集合时出现 NullPointerException