CGContextFillRect not drawing a rectangle? - iphone

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);
}

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.

multiple category for UIToolbar

So I have a class A in which I have the following:
#implementation UIToolbar (A)
- (void)drawRect:(CGRect)rect {
UIColor *color = [UIColor colorWithWhite:0.0 alpha:1.0];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColor(context, CGColorGetComponents( [color CGColor]));
CGContextFillRect(context, rect);
self.tintColor = [UIColor colorWithWhite:0.0 alpha:1.0];
}
#end
and I have a class B, which I have the following:
#implementation UIToolbar (B)
- (void)drawRect:(CGRect)rect {
UIColor *color = [UIColor colorWithWhite:10.0 alpha:1.0];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColor(context, CGColorGetComponents( [color CGColor]));
CGContextFillRect(context, rect);
self.tintColor = [UIColor colorWithWhite:0.0 alpha:1.0];
}
#end
Question is why is it only the top level category called each time? I basically want to have a different UIToolbar color/configuration for each different UIViewController, how do I do so?
A and B are not classes, they're categories. Any given class can only have one implementation of a given method at a time. If you try to override a method in more than one category, which implementation you get is undefined. Indeed, it's not recommended to override methods in categories at all -- if you need to override, you should create a subclass.
When you use this implementation , this is all uitoolbar which are custom with the theme.
If your application is developed under ios5, you can use method setBackgroundImage:forToolbarPosition:barMetrics:.
If you develop under ios < 5 , you can implement an new class inherited from uitoolbar which have a custom drawRect.

Transparent background in CoreGraphics

I am trying to get a transparent background in CG but it keeps coming out black.
I have the following code:
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
DLog(#">>> Alloc: DrawingCanvas [0x%X]", (unsigned int)self);
[self setOpaque:NO];
[self setBackgroundColor:[UIColor clearColor]];
}
return self;
}
- (void) drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect frame = rect;
int counter = 3;
CGContextClearRect(context, frame);
CGContextSetFillColorWithColor(context, [UIColor clearColor].CGColor);
CGContextFillRect(context, frame);
}
How do I get this code to show a transparent background?
With that setup and as long as you don't set clearsContextBeforeDrawing to NO, the background should already be transparent when your drawRect: method is called. Remove the CGContextClearRect and other drawing calls.
You could simply remove these lines :
CGContextClearRect(context, frame);
CGContextSetFillColorWithColor(context, [UIColor clearColor].CGColor);
CGContextFillRect(context, frame);
As long as you have set opaque to NO and clearColor as backgroundColor everything should be fine.
Be careful when drawing since your other drawing code may fill the background entirely (take care of [path fill] things in a non-clipped context).
I had this same problem and the solution was to set the backgroundColor property of the UIView which I was drawing in, from the parent view's class. I didn't need any code to clear the background in the UIView's class where the drawing happens.
myDrawingView.backgroundColor = [UIColor clearColor];

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);
}

Setting A CGContext Transparent Background

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.