User18474728
User18474728

Reputation: 361

CGBitmapContextCreate with undo not working well

I've struggled with undo function for few days and I really have no idea to solve this problem.

I'm making drawing function on UIViewController that is using a custom UIimageView.

The problem is when I triggered Undo function the previous drawing is gone well but when I tried to draw again then the removed drawing appeared again with current drawing.

here is my code. If you can see any problem please let me know! It will be really helpful. Thank you!

- (IBAction)Pan:(UIPanGestrueRecognizer *)pan {
    CGContextRef ctxt = [self drawingContext];

    CGContextBeginPath(ctxt);
    CGContextMoveToPoint(ctxt, previous.x, previous.y);
    CGContextAddLineToPoint(ctxt, current.x, current.y);
    CGContextStrokePath(ctxt);

    CGImageRef img = CGBitmapContextCreateImage(ctxt);
    self.costomImageView.image = [UIImage imageWithCGImage:img];
    CGImageRelease(img);
    previous = current;
    ...
}

- (CGContextRef)drawingContext {
    if(!context) { // context is an instance variable of type CGContextRef
        CGImageRef image = self.customImageView.image.CGImage;
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        if(!colorSpace) return nil;
        context = CGBitmapContextCreate(NULL,
                                        CGImageGetWidth(image), CGImageGetHeight(image),
                                        8, CGImageGetWidth(image) * 4,
                                        colorSpace, kCGImageAlphaPremultipliedLast
                                        );
        CGColorSpaceRelease(colorSpace);
        if(!context) return nil;
        CGContextConcatCTM(context, CGAffineTransformMake(1,0,0,-1,0,self.customeImageView.image.size.height));

        CGContextSaveGState(context);
        CGContextTranslateCTM(context, 0.0, self.customImageView.image.size.height);
        CGContextScaleCTM(context, 1.0, -1.0);
        CGContextDrawImage(context, (CGRect){CGPointZero,self.customImageView.image.size}, image);
        CGContextRestoreGState(context);

        CGContextSetLineCap(context, kCGLineCapRound);
        CGContextSetLineWidth(context, 4.f);
        CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
    }
    return context;
}

Upvotes: 1

Views: 59

Answers (1)

Will Jones
Will Jones

Reputation: 2201

I'm unsure what you're trying to do is supported by the UndoManager

What I'd personally do is something like this:

  1. Create an NSMutableArray to contain all of your drawing strokes. A struct with two Point instances in it should do for this task. If you want to go fancy, you could add a UIColor instance to set the colour and more variables for other style information as well.

  2. When your Pan gesture starts, record the point at which it starts. When it ends, record that point, create an instance of your struct and add it to the array.

  3. Have a render procedure that clears the graphics context, iterates through the array and draws to the screen.

For undo functionality, all you need to do is remove the last entry from the array and re-render.

Upvotes: 1

Related Questions