开发者

Draw and Erase Lines with Touch

开发者 https://www.devze.com 2023-03-11 15:23 出处:网络
I have a background image (ImageBG) and a foreground image (ImageFG) in separate UIImage开发者_如何学运维Views. They are the same size and, as the name implies, ImageBG is behind ImageFG so you can\'t

I have a background image (ImageBG) and a foreground image (ImageFG) in separate UIImage开发者_如何学运维Views. They are the same size and, as the name implies, ImageBG is behind ImageFG so you can't see ImageBG.

If the user starts to "draw" on them, instead of a line appearing where the user touches the screen, I want that portion of ImageFG to become transparent and reveal ImageBG.

The closest thing I can think of is a scratch-and-win.

I know how to do the drawing on a graphics context, but when I draw a transparent line (alpha = 0), well... I get a transparent line on top of whatever is currently in my graphics context, so basically nothing is drawn. This is what I use to set the stroke color.

CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1.0, 0.0, 0.0, 0.0)

What am I doing wrong? I know this is possible because there are apps out there that do it.

Any hints, tips or direction is appreciated.


So you have a layer that is some image like the grey stuff you want to scratch off, you write this image (in this example scratchImage which is a UIImageView and its UIImage .image )to the graphics context. You then stroke it with the blend mode set to kCGBlendModeClear then you save that image (with the cleared paths). This will reveal an image that you have underneath perhaps in another UIImageView. Note that in this instance, self is a UIView.

So outside touchesMoved create a variable to hold a CGPoint

CGPoint previousPoint;
CGPoint currentPoint;

Then in touchesBegan, set it to the previous point.

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];

previousPoint = [touch locationInView:self];

}

In touchesMoved, write the image to the context, stroke the image with the clear blend mode, save the image from the context, and set the previous point to the current point.

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



UITouch *touch = [touches anyObject];   
currentPoint = [touch locationInView:self];

 UIGraphicsBeginImageContext(self.frame.size);
//This may not be necessary if you are just erasing, in my case I am 
//adding lines repeatedly to an image so you may want to experiment with moving 
//this to touchesBegan or something. Which of course would also require the begin
//graphics context etc.

[scratchImage.image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)]; 

CGContextSaveGState(UIGraphicsGetCurrentContext());
CGContextSetShouldAntialias(UIGraphicsGetCurrentContext(), YES); 
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 5.0);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0.25, 0.25, 0.25, 1.0);
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, nil, previousPoint.x, previousPoint.y);
CGPathAddLineToPoint(path, nil, currentPoint.x, currentPoint.y);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);    
CGContextAddPath(UIGraphicsGetCurrentContext(), path);
CGContextStrokePath(UIGraphicsGetCurrentContext());
scratchImage.image = UIGraphicsGetImageFromCurrentImageContext();
CGContextRestoreGState(UIGraphicsGetCurrentContext());
UIGraphicsEndImageContext();
previousPoint = currentPoint;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号