drawRect is not working In Iphone - 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];

Related

How can i call this method in self.view?

I am making this method for drawing line now what I want is to call it in another methods how can I do that, please help me out of this that how can I add this in self.view?
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 5.0);
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGFloat dashArray[] = {2,6,4,2};
CGContextSetLineDash(context, 3, dashArray, 4);
CGContextMoveToPoint(context, 10, 200);
CGContextAddQuadCurveToPoint(context, 150, 10, 300, 200);
CGContextStrokePath(context);
}
Mark the view as needing a redraw:
[self.view setNeedsDisplay];
See reference.
[self.view setNeedsDisplay];
This will call your draw rect method.

How to draw line on the UIImageView not for UIView?

How to draw a line on the UIImageView? I am using the UIImageView Sub Class, Its not support drawRect: method. I want to draw a line on the image view. How can I do this? Please help me. I am using below code for draw line.
- (void)drawRect:(CGRect)rect {
CGContextRef c = UIGraphicsGetCurrentContext();
CGFloat red[4] = {1.0f, 0.0f, 0.0f, 1.0f};
CGContextSetStrokeColor(c, red);
CGContextBeginPath(c);
CGContextMoveToPoint(c, 5.0f, 5.0f);
CGContextAddLineToPoint(c, 50.0f, 50.0f);
CGContextStrokePath(c);
}
The following code works by creating a new image the same size as the original, drawing a copy of the original image onto the new image, then drawing a 1 pixel line along to the top of the new image.
// UIImage *originalImage = <the image you want to add a line to>
// UIColor *lineColor = <the color of the line>
UIGraphicsBeginImageContext(originalImage.size);
// Pass 1: Draw the original image as the background
[originalImage drawAtPoint:CGPointMake(0,0)];
// Pass 2: Draw the line on top of original image
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 1.0);
CGContextMoveToPoint(context, 0, 0);
CGContextAddLineToPoint(context, originalImage.size.width, 0);
CGContextSetStrokeColorWithColor(context, [lineColor CGColor]);
CGContextStrokePath(context);
// Create new image
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
// Tidy up
UIGraphicsEndImageContext();
First, I wouldn't use a UIImageView. In fact the docs say...
If your subclass needs custom drawing code, it is recommended you use
UIView as the base class.
Use a UIView.
In the UIView add a UIImageView subView and put the image in there. Now you can do you custom drawing in the drawRect method of the UIView and it will appear on top of the image.
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
CGContextSetLineWidth(context, 5.0);
CGContextStrokeRect(context, self.bounds);
}
If this isn't working then the drawRect method probably isn't being called. Set a breakpoint to test it.
The best way to go about it in my opinion would be to take a invisible UIView of the same size as UIImageView for drawing and implement the touch methods on the UIView for drawing.
you can use something like:
CGPoint temp=[touch locationInView:self];
Use this in methods like:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
Store all the points in an array and then draw those points on the UIImageView as it is.
Refer to Muhammad Saad Ansari
With Swift
func drawLines ( originalImage:UIImage, lineColor:CGColor ) -> UIImage{
UIGraphicsBeginImageContextWithOptions(originalImage.size,false,0.0)
originalImage.drawInRect(CGRectMake( 0, 0, originalImage.size.width, originalImage.size.height ))
let context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 5.0);
CGContextMoveToPoint(context, 0, 0);
CGContextAddLineToPoint(context, originalImage.size.width, 0);
CGContextSetStrokeColorWithColor(context,lineColor);
CGContextStrokePath(context);
// Create new image
var newImage = UIGraphicsGetImageFromCurrentImageContext();
// Tidy up
UIGraphicsEndImageContext();
return newImage
}

Quartz 2d trying to redraw a triangle

I'm developing an iPhone app.
I have the following class:
#import "Triangulo.h"
#implementation Triangulo
#synthesize minusValue;
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
// Initialization code
}
return self;
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
CGSize size = rect.size;
CGPoint origin = {10.0f, size.height - 10.0f};
[self drawLineAtOrigin:origin withLength:size.width - 10.0f];
CGPoint origin2 = {10.0f, size.height - 20.0f};
CGSize size2 = {size.width - minusValue, 20.0f};
[self drawTriangleAtOrigin:origin2 withSize: size2 inRect: rect];
}
- (void)drawLineAtOrigin:(CGPoint)origin withLength:(float)length {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor);
CGContextMoveToPoint(context, origin.x, origin.y);
CGContextAddLineToPoint(context, length, origin.y);
CGContextStrokePath(context);
}
- (void)drawTriangleAtOrigin:(CGPoint)origin withSize:(CGSize)size inRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClearRect(UIGraphicsGetCurrentContext(), rect);
CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
CGContextMoveToPoint(context, origin.x, origin.y);
CGContextAddLineToPoint(context, size.width, origin.y);
CGContextAddLineToPoint(context, size.width, origin.y - size.height);
CGContextAddLineToPoint(context, origin.x, origin.y);
CGContextFillPath(context);
CGContextStrokePath(context);
}
- (void)dealloc {
[super dealloc];
}
#end
This UIView is part of UIViewController.view. I've add in UIViewController.h as:
IBOutlet Triangulo *triangulo;
...
#property (nonatomic, retain) IBOutlet Triangulo *triangulo;
On UIViewController I have a button to modify Triangulo:
- (IBAction)btnDrawTriangleClicked:(id)sender {
triangulo.minusValue += 10.0f;
CGRect rect = CGRectMake(0, 0, 280, 50);
[triangulo drawRect: rect];
}
But I can't draw anything because UIGraphicsGetCurrentContext is always nil.
Any advice?
Add this code to your Triangulo class:
- (void)setMinusValue:(double)aMinusValue {
minusValue = aMinusValue;
[self setNeedsDisplay];
}
And then the btnDrawTriangleClicked: method to the following:
- (IBAction)btnDrawTriangleClicked:(id)sender {
triangulo.minusValue += 10.0f;
}
Now when you alter the minusValue, Triangulo automatically flags itself as needing redisplay. (See The View Drawing Cycle for more info). As Deepak stated, you never call drawRect: yourself (unless you're within the drawRect: method itself, and you're calling [super drawRect:frame];). The drawRect: method is called automatically by the system, and it always makes sure that a valid CGGraphicsContext is set up beforehand. Since you were calling it directly, that preparation work wasn't being done, so UIGraphicsGetCurrentContext() usually returned NULL.
You should never call drawRect: directly. You should call either setNeedsDisplay or setNeedsDisplayInRect: whenever you want to redraw the view. rect that is passed to drawRect: is not a random value that is passed. It tells you the portion of the view's bounds that need to be redrawn.

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.