I am drawing an ellipse using core graphics in iOS. The area near the corners of the ellipse are black in color. I want it to be clearColor. How do I get about this?
CGContextAddEllipseInRect(context, ellipseFrame);
CGContextSetFillColorWithColor(context, fillColor);
CGContextFillEllipseInRect(context, ellipseFrame);
I am sorry. I don't have enough reputations to add the screenshot of my output.
Clear the context before you start drawing:
CGContextClearRect(context, ellipseFrame);
If you are drawing ellipse in drawRect method of UIView subclass,
the area near the corners of the ellipse must be taking the background color of UIView.
Setting its backgroundColor to clearColor should sove the issue.
In UIView or NSView you draw from back to front.
You can think of the code you write in drawRect: as procedural back to front drawing instructions.
If you see black corners you probably have a containing view that is isOpaque or need to first do [[NSColor clearColor] fill] before subsequent drawing in drawRect:
Related
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?
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.
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:
Background View - This will be view that has the proper background color or image
Overlay View - This view will detect the touches etc and then draw all of the brush strokes on top. The background color of this view can then be [UIColor clearColor] so when you draw the brush images, the alpha will be filled with [UIColor clearColor]. Basically the same view you have now, just with a clear background.
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
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
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]
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.
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.
I would like to draw a glow-ish border around a UIView which is roughly 5px from the actual UIView itself.
Please could you tell me how I could achieve this?
Probably the easiest way is to create a shadow, but use a light color instead of a dark one. Shadow details can be found here: How do I draw a shadow under a UIView? and here.
Something like this should get the ball rolling:
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextSetShadowWithColor(context, CGSizeMake(0, 0), 10,
[UIColor whiteColor].CGColor);
[super drawRect:rect];
CGContextRestoreGState(context);
}
Update: I just tried this out. You will have to use this code on the superview of the glowing view for it to work properly.
The first thing I would try is to embed the UIView within a UIView which has the glow image. If the glow effect is just an image, then you create a UIView containing the glow image that is 10 px taller and wider than the UIView being surrounded. This will allow for 5 px of extension on all 4 sides. You can do all this quickly and easily using Interface Builder.
If you want the glow effect to look really cool, considering creating a collection of glow images that when viewed as a sequence will show sort of a moving glow effect. You can then use this collection of images in the UIView and turn on animation. All UIView controls have animation support built in.
Hope this helped. Good Luck.
I have an UIView which has white background color set.
I have set the blending mode of the CGContext of the UIView as 'kCGBlendModeCopy'.
Then,
1. Draw an UIImage in that CGContext
2. Draw a path with alpha as 0 in that context.
The transparent area covered by the path appears in black whereas my expected output was that it should be UIView's background color (i.e. white).
Does anyone knows what is the problem here?
Thanks in advance,
Regards,
Deepa
There is no problem here and hence no solution. Since we are drawing on the UIView's context with transparency, we can see the screen that is in black color. The drawing hierarchy is like this:
1. Black screen
2. On this transparent window is kept. Through this window we can see the screen
3. A view that is partially transparent is kept on this window. Through this view we can see window(Window is transparent and hence we can see screen)
(View is partially transparent because I am drawing part of the View with transparent path)
Hope this helps you Naren
Maybe this article can help you..
http://losingfight.com/blog/2007/08/18/how-to-implement-a-basic-bitmap-brush/
I understood the problem after putting some more effort:
CGContext is not a separate drawing layer of UIView. UIView is a cocoa wrapper for CGContext drawing. Since I am drawing the path with transparency, the screen behind the UIView is visible.
I am trying to draw a line on top of a background image in my UIView tracing the movements of the user's finger. I can accomplish this by drawing the UIImage as my background and then doing my line drawing in drawRect but I have to load the image each time drawRect is called and it makes performance sluggish. Alternatively, if I use a UIImageView as my background image (just adding it to the view in IB or programatically) the lines disappear when it is dragged over the image. Is there a way to tell the lines to draw on top of the UIImageView. Thanks for your help.
Here is my code using the UIImage method:
- (void)drawRect:(CGRect)rect {
UIImage *imageField = [UIImage imageNamed:#"field.jpg"];
CGRect rectForImage=CGRectMake(0,0,200,200);
[imageField drawInRect:rectForImage];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextMoveToPoint(context, x1, y1);
CGContextAddLineToPoint(context, x2, y2);
CGContextStrokePath(context);
}
Adding the image as the background view is the correct way to do it. The problem lies in the fact that you added the image directly to the view. Subviews are displayed on top of a view, not behind it. Correctly use a container view that holds the image view as a background, and then your line-drawing view on top of that.
You can try drawing your (opaque) lines to a transparent CALayer, and placing that CALayer on top of your UIView, thus above the background UIImage.
In my drawRect method, I am drawing a PNG image. On top of that, I want to draw a rect with a 20% alpha color, like this:
[[UIColor colorWithWhite:0.0 alpha:0.2] set];
UIRectFill(rect);
The problem is, that the alpha property seems to get ignored. No alpha is applied at all, just a black rectangle is drawn. How can I fix this? Thanks in advance!
Use CGContextSetBlendMode() before you draw the rect.
Set your view background color to transparent… It should work.