I wam trying to implement undo button , everything is working fine and i am able to cache the action but somehow previously drawn lines are still there , they should disappear on every undoclick action Please help
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
path = [[UIBezierPath alloc] init];
mouseSwiped = NO;
UITouch *touch = [touches anyObject];
lastPoint = [touch locationInView:self.view];
CGPoint p = [touch locationInView:self.view];
[path moveToPoint:p];
[pathArray addObject:path];
// NSLog(@"%@",pathArray);
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
mouseSwiped = YES;
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self.view];
CGPoint p = [touch locationInView:self.view];
[path addLineToPoint:p];
UIGraphicsBeginImageContext(self.view.frame.size);
[self.tempDrawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), brush );
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red, green, blue, 1.0);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(),kCGBlendModeNormal);
CGContextStrokePath(UIGraphicsGetCurrentContext());
self.tempDrawImage.image = UIGraphicsGetImageFromCurrentImageContext();
[self.tempDrawImage setAlpha:opacity];
UIGraphicsEndImageContext();
lastPoint = currentPoint;
[self.view setNeedsDisplay];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView:self.view];
[path addLineToPoint:p];
if(!mouseSwiped) {
UIGraphicsBeginImageContext(self.view.frame.size);
[self.tempDrawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), brush);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red, green, blue, opacity);
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
CGContextFlush(UIGraphicsGetCurrentContext());
self.tempDrawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
UIGraphicsBeginImageContext(self.mainImage.frame.size);
[self.mainImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) blendMode:kCGBlendModeNormal alpha:1.0];
[self.tempDrawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) blendMode:kCGBlendModeNormal alpha:opacity];
self.mainImage.image = UIGraphicsGetImageFromCurrentImageContext();
self.tempDrawImage.image = nil;
UIGraphicsEndImageContext();
[self mainImage];
[self.view setNeedsDisplay];
[path removeAllPoints];
}
with following undo function and patharray count is decrementing at every click but draw lines are still there
-(IBAction)undoButtonClicked:(id)sender
{
NSLog(@"%s", __FUNCTION__);
NSLog(@"pathArray count is %i", [pathArray count]);
if([pathArray count]>0){
UIBezierPath *_path=[pathArray lastObject];
[bufferArray addObject:_path];
[pathArray removeLastObject];
//self.tempDrawImage.image;
[self.view setNeedsDisplay];
}
}
It looks like you’re using the
tempImageivar to accumulate the strokes of the drawing, but when you click undo you don’t do anything to erase the lines that have already been drawn there. I don’t know how complex your drawing requirements are. If they’re simple, you could just iterate overpathArrayin the-drawRectof the view calling-strokeon each path (you’d need to set lineWidth etc on the path or in the view each time you draw a stroke, of course). As a simple optimization you could calculate the bounds of new/deleted strokes and then callsetNeedsDisplayInRect:on the appropriate portion of the view. As it is you’re updatingtempImageevery time the touch moves, which I imagine has quite a high overhead.