0

I'm trying to add an undo/redo function to an iOS app. I want to be able to draw several lines, then undo each one.. I can erase the whole thing, but that's not good enough... I would really appreciate help as this is my first foray into using CG..

My .h declarations include:

CGPoint lastPoint;
NSMutableArray *pathArray;
UIBezierPath *myPath;

In .m, I have:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"%s", __FUNCTION__);
    UITouch *touch = [touches anyObject];
    myPath=[[UIBezierPath alloc]init];
    lastPoint = [touch locationInView:self.view];
    [myPath moveToPoint:lastPoint];
    lastPoint.y -= 20;
    [pathArray addObject:myPath];
    NSLog(@"pathArray count is %i", [pathArray count]);

}


- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"%s", __FUNCTION__);
    UITouch *touch = [touches anyObject];   
    CGPoint currentPoint = [touch locationInView:self.view];
    currentPoint.y -= 20;   
    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(), brush);
    CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red, green, blue, 1.0);
    CGContextBeginPath(UIGraphicsGetCurrentContext());
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
    CGContextStrokePath(UIGraphicsGetCurrentContext());

    drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
    savedImage.image = drawImage.image;

    UIGraphicsEndImageContext();

    lastPoint = currentPoint;

}

At the end of touchesBegin, the pathArray count is always zero.. :(

To implement the undo, I'm using this code:

- (void)undoButtonTapped {
    NSLog(@"%s", __FUNCTION__);
    NSLog(@"pathArray count is %i", [pathArray count]);
    if([pathArray count]>0){
        UIBezierPath *_path=[pathArray lastObject];
        [bufferArray addObject:_path];
        [pathArray removeLastObject];
        [self.view setNeedsDisplay];
    }

}

count here is also zero..

All of this is being handled in a UIViewController. I would welcome any advice/improvements/suggestions.

Thanks

ICL1901
  • 7,632
  • 14
  • 90
  • 138

1 Answers1

1

I'd say that the reason that [pathArray count] is zero in touchesBegan is that nowhere in your code do I see

pathArray = [[NSMutableArray alloc] init];

So you are sending messages to a null pointer (which is allowed but does nothing).

So are you allocating pathArray? Or is it null??

Peter M
  • 7,309
  • 3
  • 50
  • 91
  • Peter, thanks for that. Now the array counts are incremented, and when I select undo, the count is decremented. However, the line is not removed. Any other advice...? – ICL1901 Apr 12 '12 at 15:52
  • 1
    @DavidDelMonte You can't undraw a segment of a path. You can only redraw the view that contains the path (after the last segment has been removed). Calling `setNeedsDisplay` is the first step, but you will have to add code to `drawRect` for the view that the path is displayed on. And in there that is where you redraw the path. – Peter M Apr 12 '12 at 16:37
  • I'm afraid I'm still stumped. I seem to be able to "undo" the whole screen, or nothing. I would really appreciate a small code snippet to get me started. Thanks! – ICL1901 Apr 12 '12 at 18:23
  • @DavidDelMonte OK .. if you look at a question I asked http://stackoverflow.com/questions/9468707/ios-cakeyframeanimation-rotationmode-on-uiimageview-solved in my **Edit March 22** I posted a link to source code on GitHub (https://github.com/JoalahDesigns/PathMove ) that is a test app of mine that draws a bezier path in the `drawRect` of a view. I am building my path differently from yours, but you will be able to see in general where the redraw code will go (see class JdGraphicView), and the use of 'setNeedsDisplay'. You should be able to down load the code and build the app. – Peter M Apr 12 '12 at 18:32
  • Thanks Peter, you helped me no end! I have another question to ask but I'll do it separately. – ICL1901 Apr 13 '12 at 12:22
  • @DavidDelMonte No problem .. a lot of people on here have help me too! – Peter M Apr 13 '12 at 17:44