【问题标题】:Why does my Core Graphics drawing code run slow?为什么我的 Core Graphics 绘图代码运行缓慢?
【发布时间】:2014-01-29 19:46:15
【问题描述】:

当我尝试在我的 iPad“绘图应用程序”中绘图时,它会使用大量内存并最终崩溃(或者至少只是绘制非常滞后的线条)。我一直在寻找有关“绘图应用程序”的示例。我只发现 2 个有效,但在尝试利用它们时都落后了很多。如果我使用 iPhone/iPad 模拟器绘制流畅,但在我的 iPad 2G 上它滞后很多:(

我的应用程序的真正目的是一个“签名应用程序”,如果它可以帮助任何人;)

如果您对绘图应用程序有任何经验(或者可以看到我的代码错误的地方),请留下答案。将不胜感激!

我的代码如下(也是截图):

ViewController.m:

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];
drawImage = [[UIImageView alloc] initWithImage:nil];
drawImage.frame = self.view.frame;
[self.view addSubview:drawImage];
self.view.backgroundColor = [UIColor lightGrayColor];
mouseMoved = 0;

}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

mouseSwiped = NO;
UITouch *touch = [touches anyObject];

lastPoint = [touch locationInView:self.view];

}


- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

mouseSwiped = YES;

UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self.view];

UIGraphicsBeginImageContext(self.view.frame.size);
[drawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 3.0);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 255.0, 255.0, 255.0, 1.0);
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

lastPoint = currentPoint;

mouseMoved++;

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

}

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

if(!mouseSwiped) {
    UIGraphicsBeginImageContext(self.view.frame.size);
    [drawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
    CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
    CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 3.0);
    CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 255.0, 255.0, 255.0, 1.0);
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
    CGContextStrokePath(UIGraphicsGetCurrentContext());
    CGContextFlush(UIGraphicsGetCurrentContext());
    drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
}
}


- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}

@end

ViewController.h:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController {
    CGPoint lastPoint;
    UIImageView *drawImage;
    BOOL mouseSwiped;
    int mouseMoved;
}


@end

【问题讨论】:

  • 您是否尝试过使用 Instruments 或其他工具来分析代码和测试性能?你不能指望我们简单地给你答案。

标签: ios objective-c drawing cgcontext


【解决方案1】:

大部分性能问题可能是由于在每次触摸事件上绘制前一个图像。 [drawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];

我会尝试的第一件事是创建一个从 UIView 派生的视图并在 drawRect 中进行所有绘图。这样,您就不会阻止在每个触摸事件上绘图。当您响应触摸事件时,您需要在自定义视图上调用 setNeedsDisplay。

我要尝试的第二件事是使用 CAShapeLayer 作为支持自定义视图的图层。当你这样做时,你不需要覆盖 drawRect。你只需要给图层点数。

【讨论】:

  • 我还应该提到,当您覆盖 DrawRect 时,每次只绘制整个路径并且不要使用辅助图像。使用 UIBezierPath 或 CGPath 构建您的路径。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-08
  • 1970-01-01
  • 2016-05-17
  • 1970-01-01
  • 2016-12-07
  • 2012-05-15
  • 1970-01-01
相关资源
最近更新 更多