Reputation: 155
When I try to draw in my iPad "draw application" it uses HUGE amounts of memory and eventually crashes (or at least just draw lines VERY laggy). I have been looking a lot for examples on "Drawing apps". I only found 2 that worked, but both lagged A LOT when trying to draw on them. If I use the iPhone/iPad simulator is draws smoothly, but on my iPad 2G it lags a lot :(
The real purpose of my application is a "Signature app", if it will help anybody ;)
If you got any experience with drawing apps (or can see where my code is wrong), please leave an answer. It will be appreciated!!
My code is listed below (also a screenshot):
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
Upvotes: 1
Views: 946
Reputation: 5121
Most of the performance problem is probably from drawing the previous image on EVERY touch event. [drawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
The first thing I would try is to create a view derived from UIView and do all drawing in drawRect. That way you are not blocking for drawing on every touch event. When you respond to touch events you will need to call setNeedsDisplay on your custom view.
The second thing I would try is to use a CAShapeLayer for the layer backing on your custom view. When you do this you don't need to override drawRect. You just need to give the layer the points.
Upvotes: 1