10

I am looking for a way of being able to erase a UIImageView from the screen. When I say erase I don't mean [imageView removeFromSuperview];, I mean to erase parts of the image by scribbling your finger on the screen. Where ever your finger is, that is the portion of the image that is erased. I just can't find any help with this.

I would image in has to do with Quartz? If so, I'm not real good with that. :(

I guess the best example is a Lottery ticket. Once you scratch the portion of the ticket, that area beneath it reveals. Anyone know how to accomplish this?

Thank you!

Update:

The following code is what did the trick. Thank you!
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    lastTouch = [touch locationInView:canvasView];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    currentTouch = [touch locationInView:canvasView];

    CGFloat brushSize = 35;
    CGColorRef strokeColor = [UIColor whiteColor].CGColor;

    UIGraphicsBeginImageContext(scratchView.frame.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [canvasView.image drawInRect:CGRectMake(0, 0, canvasView.frame.size.width, canvasView.frame.size.height)];
    CGContextSetLineCap(context, kCGLineCapRound);
    CGContextSetLineWidth(context, brushSize);
    CGContextSetStrokeColorWithColor(context, strokeColor);
    CGContextSetBlendMode(context, kCGBlendModeClear);
    CGContextBeginPath(context);
    CGContextMoveToPoint(context, lastTouch.x, lastTouch.y);
    CGContextAddLineToPoint(context, currentTouch.x, currentTouch.y);
    CGContextStrokePath(context);
    canvasView.image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    lastTouch = [touch locationInView:canvasView];
}

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

}
Serkan Arıkuşu
  • 5,549
  • 5
  • 33
  • 50
Alec
  • 177
  • 2
  • 16
  • I imagine an easier way if its on a simple background wouldn't be erasing a UIImage but simple drawing the background color on top of it using Quartz :) – Ryan Poolos Jul 14 '12 at 01:22
  • @RyanPoolos No because there is a UIView underneath it with multiple images. I want to erase the top image to reveal the UIView beneath it. – Alec Jul 14 '12 at 01:24
  • Then you can't use a UIImageView at all. You're going to have to draw it into a custom Quartz layer and do it the hard way. – Ryan Poolos Jul 14 '12 at 01:58
  • @Alec thanks for the code that is what i need exactly thanks so much Alec – Arun Aug 08 '12 at 13:07
  • @Spynet I'm glad that this has helped someone else. Any hints to what your cooking up with this? haha – Alec Aug 10 '12 at 06:43
  • @Alec this my Preparation my friend... please see that man.... http://www.screencast.com/t/fuvc4LVbX – Arun Aug 13 '12 at 15:07
  • @Spynet That's cool bro, keep it up! – Alec Aug 18 '12 at 07:34
  • @Alec thanks bro, keep posting the code... – Arun Aug 22 '12 at 06:17
  • hello i cant to redraw erased image using this method can any one have idea for that pls help me – Kaushik Movaliya Jun 08 '15 at 11:27

1 Answers1

10

You can definitely do this with a UIImageView, no custom Quartz layer required. Are you familiar with any form of drawing in iOS? Basically, you just need to keep track of the current and previous touch location using touchesBegan:, touchesMoved:, and touchesEnded.

Then you need to draw a 'line' (which in this case erases what's underneath it) between the current touch location and previous touch location using something like the following, which is taken directly from an actual application I developed that did something rather similar:

UIGraphicsBeginImageContext(canvasView.frame.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[canvasView.image drawInRect:CGRectMake(0, 0, canvasView.frame.size.width, canvasView.frame.size.height)];
CGContextSetLineCap(context, lineCapType);
CGContextSetLineWidth(context, brushSize);
CGContextSetStrokeColorWithColor(context, strokeColor);
CGContextSetBlendMode(context, kCGBlendModeClear);
CGContextBeginPath(context);
CGContextMoveToPoint(context, lastTouch.x, lastTouch.y);
CGContextAddLineToPoint(context, currentTouch.x, currentTouch.y);
CGContextStrokePath(context);
canvasView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

In this code canvasView is a UIImageView. There are lots of tutorials out there for this kind of drawing. The important thing for what you want is to set the blend mode to kCGBlendModeClear. That's this line:

CGContextSetBlendMode(context, kCGBlendModeClear);
Ethan Holshouser
  • 1,402
  • 14
  • 13
  • In touchesBegan, would you set lastTouch, then in Moved, would you set lastTouch after all of the code you posted, and in touchesEnded would you set lastTouch = nil? – Alec Jul 14 '12 at 04:40
  • Close. In touchesBegan you would set lastTouch. In touchesMoved, you would set currentTouch before the drawing code and lastTouch at the end. In touchesEnded you would set currentTouch at the beginning. There is no need to set lastTouch = nil at any point. – Ethan Holshouser Jul 14 '12 at 04:46
  • It's weird, I scratch and it works, but it erases about 150 pixels downward. I didn't change any code besides the things I needed to. – Alec Jul 14 '12 at 05:05
  • How are you getting the location of the touches? Make sure you're calling `locationInView:` with the same UIImageView as the one you're trying to erase. – Ethan Holshouser Jul 14 '12 at 05:09
  • You need to use `lastTouch = [touch locationInView:canvasView];` instead of `lastTouch = [touch locationInView:self.view];`. The same goes for `currentTouch`, of course. – Ethan Holshouser Jul 14 '12 at 06:29
  • @EthanHolshouser is that possible to do undo/redo for this drawing ? – BigAppleBump Apr 14 '13 at 07:45
  • @Alec is that possible to do undo/redo for this drawing ? – BigAppleBump Apr 14 '13 at 07:52
  • @BigAppleBump it's definitely possible, but if you need help figuring out how I would suggest asking a new question. – Ethan Holshouser Apr 14 '13 at 22:47
  • hello i can't to redraw erased image using this method can any one have idea for that pls help me – – Kaushik Movaliya Jun 09 '15 at 12:16