Setting A CGContext Transparent Background - iphone

I am still struggling with drawing a line with CGContext. I have actually go to line to draw, but now I need the background of the Rect to be transparent so the existing background shows thru. Here's my test code:
(void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [UIColor clearColor].CGColor);
CGContextSetAlpha(context,0.0);
CGContextFillRect(context, rect);
CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
CGContextSetLineWidth(context, 5.0);
CGContextMoveToPoint(context, 100.0,0.0);
CGContextAddLineToPoint(context,100.0, 100.0);
CGContextStrokePath(context);
}
Any ideas?

After UIGraphicsGetCurrentContext() call CGContextClearRect(context,rect)
Edit:
Alright, got it.
Your custom view with the line should have the following:
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self setBackgroundColor:[UIColor clearColor]];
}
return self;
}
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClearRect(context, rect);
CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
CGContextSetLineWidth(context, 5.0);
CGContextMoveToPoint(context, 100.0,0.0);
CGContextAddLineToPoint(context,100.0, 100.0);
CGContextStrokePath(context);
}
My test used this as a very basic UIViewController:
- (void)viewDidLoad {
[super viewDidLoad];
UIImageView *v = [[UIImageView alloc] initWithFrame:self.view.bounds];
[v setBackgroundColor:[UIColor redColor]];
[self.view addSubview:v];
TopView *t = [[TopView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:t];
[v release];
[t release];
}

Easy way:
- (id)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame]))
{
self.opaque = NO;
}
return self;
}
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClearRect(context, rect);
//your code
}

Init a context with opaque == false, Swift 3
UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
opaque
A Boolean flag indicating whether the bitmap is opaque. If you know the bitmap is fully opaque, specify true to ignore the alpha channel and optimize the bitmap’s storage. Specifying false means that the bitmap must include an alpha channel to handle any partially transparent pixels.

This is what worked for me with a UIImage which had been manually added using InterfaceBuilder.
- (id)initWithCoder:(NSCoder *)aDecoder {
if(self = [super initWithCoder:aDecoder]) {
self.backgroundColor = [UIColor clearColor];
}
return self;
}
-(void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
CGContextSetLineWidth(context, 5.0);
CGContextMoveToPoint(context, 100.0,0.0);
CGContextAddLineToPoint(context,100.0, 100.0);
CGContextStrokePath(context);
}
David Kanarek's answer only works when you're manually creating your own UIImageView. If you've created a UIView and manually added it via Interface Builder then you will need a different approach like this calling the initWithCoder method instead.

I have the same problem, then I find it is.
I overwrite the init Method is -(id)initWithFrame:(CGRect)rect.
In this method self.background = [UIColor clearColor];
but i use this view in xib file !!! That will call the init method is
-(id)initWithCoder:(NSCoder*)aDecoder;
So overwrite all the init Method and setup BackgroundColor will work OK.

CGContextClearRect(context,rect)
If the provided context is a window or bitmap context, Quartz effectively clears the rectangle. For other context types, Quartz fills the rectangle in a device-dependent manner. However, you should not use this function in contexts other than window or bitmap contexts.

you can create a image context with this code:
cacheContext = CGBitmapContextCreate (cacheBitmap, size.width, size.height, 8, bitmapBytesPerRow, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaPremultipliedLast);
CGContextSetRGBFillColor(cacheContext, 0, 0, 0, 0);
CGContextFillRect(cacheContext, (CGRect){CGPointZero, size});
the key is kCGImageAlphaPremultipliedLast.

Having trouble understanding the question here, but if you're unable to have a "background" UIView show through a "top" view into which you're drawing, one solution is topView.backgroundColor = [UIColor clearColor]; I was having (I think) this same problem and this solved it for me.

Related

Make UiView sub class but background color show black color

I have taken a UiView subclass but it's background color is not changing
This class I am using these method
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:CGRectMake(50, 80, 200, 200)];
if (self)
{
// Initialization code
}
return self;
}
- (void)drawRect:(CGRect)rect{
CGContextRef context = UIGraphicsGetCurrentContext();
[[UIColor darkGrayColor]setFill];
CGContextClearRect(context, rect);
CGContextSetLineWidth(context, 2.0);
CGContextBeginPath(context);
CGContextSetStrokeColorWithColor(context, [UIColor orangeColor].CGColor);
CGContextMoveToPoint(context, 1, 1);
CGContextAddLineToPoint(context, 100, 100);
CGContextStrokePath(context); // and draw
}
I am calling this class to main view controller
Newclass *obj =[[Newsclass alloc]init];
obj.backgroundColor =[UIColor redColor];
[self.view addsubview :obj];
but background color by default show black color. It is not changing
if i implemented background-color code init with frame method or
draw rect method than not changing.
if i code it
- (id)initWithCoder:(NSCoder*)aDecoder
than it's method not called
please suggest me UIview subclass black background color how to change
First of all, you should do the color part in UIView file.
if (self = [super initWithFrame:CGRectMake(220,60, 100, 300)])
{
self.backgroundColor =[UIColor greenColor];
}
how ever you don't need to do in this case... ;)
it will definitely change your background color. But what happens next is that Draw rect method is called ,your color is no more visible as the draw rect method draws a view above it (whatever you draw in that method).
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGRect rectangle = CGRectMake(0,0,200,300);
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
CGContextFillRect(context, rectangle);
}
You just cannot directly set the background color of cgcontext, you have to fill that context with color.
please make sure that you replace rectangle by rectangular frame of your view. It works like a charm for me.

Color Overlay UIButton Image

I'm having this issue when trying to overlay a UIButton's Image with a color.
The overlay color is appearing underneath the Image.
Here is the code that I have in my drawRect method (I have subclassed UIButton):
(void)drawRect:(CGRect)rect
{
CGRect bounds = self.imageView.bounds;
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
CGContextTranslateCTM(context, 0.0, self.imageView.image.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextClipToMask(context, bounds, [self.imageView.image CGImage]);
CGContextFillRect(context, bounds);
}
Any ideas on how to get the red color on top of the Image?
Succeeded with this hacky code:
- (void)drawRect:(CGRect)rect
{
UIImage* img = [self imageForState:UIControlStateNormal];
[self setImage:nil forState:UIControlStateNormal];
CGRect bounds = self.imageView.bounds;
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [UIColor colorWithRed:1 green:0 blue:0 alpha:0.2].CGColor);
CGContextDrawImage(context, bounds, img.CGImage);
CGContextFillRect(context, bounds);
}
It seems the image is drawn after drawRect so unless you make it nil, it goes on top of whatever you draw there.
This is solution is not final. I'll edit it with what I get to next.
EDIT: The right solution is to add a semi-transparent UIView on top of the image like this:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
UIView* tintView = [[UIView alloc] initWithFrame:self.bounds];
tintView.backgroundColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:0.2];
tintView.userInteractionEnabled = NO;
[self addSubview:tintView];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
UIView* tintView = [[UIView alloc] initWithFrame:self.bounds];
tintView.backgroundColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:0.2];
tintView.userInteractionEnabled = NO;
[self addSubview:tintView];
}
return self;
}
Note: you should do this in your UIButton subclass.

CGContextFillRect not drawing a rectangle?

I have this code:
CGColorRef darkColor = [[UIColor colorWithRed:21.0/255.0 green:92.0/255.0 blue:136.0/255.0 alpha:1.0] CGColor];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, darkColor);
CGContextFillRect(context, CGRectMake(18, 62, 66, 66));
And I just put it in the viewdidload method of my view, but my view doesn't look any different than before. I've tried making it really big and bright red, but it's just not drawing. Is there some other initialization code that I need?
EDIT: After working with the answers given to me, I have this now in my veiwdidload:
[self.view addSubview:[[[imageBackground alloc] init] autorelease]];
and in imageBackground.m:
#implementation imageBackground
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.opaque = YES;
self.backgroundColor = [UIColor clearColor];
}
return self;
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
CGColorRef darkColor = [[UIColor colorWithRed:21.0/255.0 green:92.0/255.0 blue:136.0/255.0 alpha:1.0] CGColor];
darkColor = [[UIColor colorWithRed:255.0 green:0.0 blue:0.0 alpha:1.0] CGColor];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, darkColor);
CGContextFillRect(context, CGRectMake(18, 62, 66, 66));
}
#end
Imagebackground.h subclasses UIView:
#import <UIKit/UIKit.h>
#interface imageBackground : UIView
#end
I still get no results out of it though.
EDIT2: Well, I solved it myself, but then realized progrmr had already told me how to solve it. I had to use [self.view addSubview:[[[imageBackground alloc] initWithFrame:CGRectMake(0, 0, 320, 480)] autorelease]]; instead of just plain alloc init.
Thanks glorifiedhacker for lots of help as well!
You need to subclass UIView (or one of its subclasses) and override the drawRect method:
- (void)drawRect:(CGRect)rect {
CGColorRef darkColor = [[UIColor colorWithRed:21.0/255.0 green:92.0/255.0 blue:136.0/255.0 alpha:1.0] CGColor];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, darkColor);
CGContextFillRect(context, CGRectMake(18, 62, 66, 66));
}
in order to get a valid graphics context into which you can draw. From Apple's documentation on UIView:
View drawing occurs on an as-needed basis. When a view is first shown,
or when all or part of it becomes visible due to layout changes, the
system asks the view to draw its contents. For views that contain
custom content using UIKit or Core Graphics, the system calls the
view’s drawRect: method. Your implementation of this method is
responsible for drawing the view’s content into the current graphics
context, which is set up by the system automatically prior to calling
this method. This creates a static visual representation of your
view’s content that can then be displayed on the screen.
The most simply way, without subclassing, is a procedure for whole code.
void DrawRectFrame(CGContext c, CGRect rc)
{
CGContextMoveToPoint(c, rc.origin.x, rc.origin.y);
CGContextAddLineToPoint(c, rc.origin.x+rc.size.width, rc.origin.y);
CGContextMoveToPoint(c, rc.origin.x+rc.size.width, rc.origin.y);
CGContextAddLineToPoint(c, rc.origin.x+rc.size.width, rc.origin.y+rc.size.height);
CGContextMoveToPoint(c, rc.origin.x+rc.size.width, rc.origin.y+rc.size.height);
CGContextAddLineToPoint(c, rc.origin.x, rc.origin.y+rc.size.height);
CGContextMoveToPoint(c, rc.origin.x, rc.origin.y+rc.size.height);
CGContextAddLineToPoint(c, rc.origin.x, rc.origin.y);
}

drawRect is not working In Iphone

Hi i m adding UIView to window.
this view has drawRect as-
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
// Initialization code
}
return self;
}
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 2.0);
CGContextMoveToPoint(context, 0, 0);
CGContextAddLineToPoint(context, 300, 400);
CGContextStrokePath(context);
}
but this code is not drawing any line.
so any help for this??????
use
CGContextClosePath(context);
CGContextDrawPath(context, kCGPathFillStroke);
after your code.
I think Marcelo Cantos is right. You should set stroke color.
Maybe you can try this to set color.
[[UIColor blackColor] set];

Why I can't draw something on my UIView?

This is my Main View, I just want it draw some thing to test, but I find that my UI don't have any thing, here is the code:
- (void)viewDidLoad {
[super viewDidLoad];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
CGContextMoveToPoint(context, 100.0f, 100.0f);
CGContextAddLineToPoint(context, 200.0f, 200.0f);
CGContextStrokePath(context);
}
This is the sample code I copied online. I assume the code is correct, it does not have any error, but nothing appear. Or... ... this code should not paste on viewDidLoad?
viewDidLoad doesn't have a context. You will need to create an image context, do your drawing, produce an image, then add it to the view like so:
UIGraphicsBeginImageContext();
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
CGContextMoveToPoint(context, 100.0f, 100.0f);
CGContextAddLineToPoint(context, 200.0f, 200.0f);
CGContextStrokePath(context);
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *imgView = [[UIImageView alloc] initWithImage:img];
[self.view addSubview:imgView];
[imgView release];
Edit:
viewDidLoad is a UIViewController method, not a UIView method. I assume this code is in your controller, am I correct? Also, viewDidLoad is only called after loading a view from a nib. Did you use a nib (xib built with Interface Builder) or did you create your view programmatically?
To draw on the view using your code, you need to override -drawRect: instead of -viewDidLoad.
- (void)drawRect:(CGRect)rect {
[super drawRect:rect]; // not necessary
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
CGContextMoveToPoint(context, 100.0f, 100.0f);
CGContextAddLineToPoint(context, 200.0f, 200.0f);
CGContextStrokePath(context);
}