Reputation: 2356
I am trying to make a view that lets a user draw with their finger. I have a png made in Pixelmator of the brush. My drawRect: method looks like this:
- (void)drawRect:(CGRect)rect
{
NSAssert(brush != nil, @"");
for (UITouch *touch in touchesNeedingDrawing)
{
//Draw the touch
[brush drawInRect:CGRectWithPoints([touch locationInView:self], [touch previousLocationInView:self]) blendMode:0 alpha:1];
}
[touchesNeedingDrawing removeAllObjects];
}
The brush image is a png with transparency, but when I run the app, there is no transparency. Does anyone know why, and how to fix it?
Edit:
I discovered that the image is transparent, but when I call drawInRect
, the image draws the transparent pixels as the background color of the view. Is there a CGBlendMode I can use to fix this?
Upvotes: 8
Views: 5873
Reputation: 53561
Your problem is a fundamental misconception of how drawRect:
actually works. Every time you draw something into the current graphics context, everything that was there previously will be cleared (so that only the backgroundColor
remains).
Since you're only drawing the current touch(es) (touchesNeedingDrawing
is emptied), there's nothing under the rectangle you're filling that could show the transparency of the image you're drawing, so the background color shows through.
You basically have two options to resolve this:
1) Keep all touches that contribute to the drawing around (don't empty the touchesNeedingDrawing
array) and redraw all of them every time – this is going to be easy but quite slow.
2) Draw into a buffer of some kind (e.g. a UIImage
, using UIGraphicsBeginImageContext
etc.). Every time your drawing changes, create a new buffer. Draw the old buffer into the new buffer and the images for the new stroke on top of it.
Upvotes: 0
Reputation: 7510
A possible issue is that you are setting the blendMode to 0. I suggest using the -drawInRect:
method without a blend mode. The issue may also be that your view has a black background, but that is doubtful. I would also suggest attempting to display the UIImage in a UIImageView as a test. The issue may be related to the way that PixelMator exports images.
Upvotes: 0
Reputation: 4932
Solution is very simple, testes on my own project. In class which you updated with custom - (void)drawRect:(CGRect)rect
set in -(id)init
background color for self
[self setBackgroundColor:[UIColor clearColor]];
And thats all. Tested on my project.
Upvotes: 5
Reputation: 10475
i think you should try destination out blend mode: kCGBlendModeDestinationOut
.
You could also draw at point instead draw in rect:
[brush drawAtPoint:[touch locationInView:self] blendMode:kCGBlendModeDestinationOut alpha:1]
Upvotes: 0
Reputation: 281
It seems like it could be taking the current fill color of the context.
Try setting the fill color for the context with CGContextSetFillColorWithColor() to [UIColor clearColor].CGColor
If that doesn't work, the only other solution that is simple and shouldn't have a performance hit is to have 2 views:
Note: You shouldn't need to mess with the blend mode to make this work. You should be able to use the default drawInRect: method
Upvotes: 1
Reputation: 1615
Is the brush png loaded to an imageView? That is, the variable brush is an object of UIImageView, isn't it? If so, perhaps simple
brush.backgroundColor = [UIColor clearColor];
will help
Upvotes: 0