drawing rectangle on button click in viewcontroller class in objective c IOS5 - iphone

simply I am beginner in developing on ipad and I need to draw rectangle at point x,y with width and height when i clicked or touched button .
I searched on google but i didn't find anything working in button handler

Create rectangleButton in viewDidLoad method and write -(void)rectangleButtonSelected method in your ViewController.m. And also create class RectangleView of UIView.
-(void)rectangleButtonSelected{
RectangleView *temp = [[RectangleView alloc] initWithFrame:CGRectMake(0, 0, 60, 40)];
temp.center = CGPointMake(arc4random()%100, arc4random()%200);
NSLog(#"The Main center Point : %f %f",temp.center.x,temp.center.y);
[self.view addSubview:temp];
}
Implement - (void)drawRect:(CGRect)rect method in RectanglerView.m
- (void)drawRect:(CGRect)rect
{
// Drawing code
context =UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
// And draw with a blue fill color
CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1.0);
// Draw them with a 2.0 stroke width so they are a bit more visible.
CGContextSetLineWidth(context, 2.0);
CGContextAddRect(context, self.bounds);
CGContextStrokePath(context);
// Close the path
CGContextClosePath(context);
// Fill & stroke the path
CGContextDrawPath(context, kCGPathFillStroke);
}
I hope it will be helpful to you

You actually need to do this with state. There's only one place you're allowed to do drawing, and that's in drawRect:. So, when the user clicks the button, you need to set some instance variable, like _isShowingRectangle or something, then call setNeedsDisplay on your custom UIView where you're doing your drawing.
Then, in your custom view's drawRect:, you can check if that state variable is set, and draw (or not draw) the rectangle. The code for drawing depends on which graphics layer you're using, but it's probably going to be something like
CGContextRef ctxt = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(ctxt,[[UIColor blackColor] CGColor]);
CGContextSetLineWidth(ctxt,3.0);
CGContextStrokeRect(ctxt,CGRectMake(10,20,100,50));

Related

iPhone Quartz Drawing Eraser

I am trying to make an iPhone application with erasing. I am running into 2 problems, if you have a solution for either one please answer this. I would like to erase part of an image.
1) I am currently just clearing the rect but it has a square edge. I would like it to be round, I have previously tried translating but this does not work. I also need it to translate/rotate as few times as possible to maintain the same performance.
2) In addition I wanted to know if there are any other ways of erasing. When erasing fast it is erasing ever 1/2 inch. Is there a way to stroke a path and clear the rect or something? Sorry if this is hard to understand.
CGRect circleRect = CGRectMake([touch CGPointValue].x, [touch CGPointValue].y, 25, 25);
CGContextClearRect(currentContext,circleRect);
This code should do what you're looking for:
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetLineWidth(context, self.strokeWidth);
CGContextSetBlendMode(context, kCGBlendModeClear);
CGContextSetStrokeColorWithColor(context, [[UIColor clearColor] CGColor]);
CGContextBeginPath(context);
CGContextMoveToPoint(context, lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(context, currentPoint.x, currentPoint.y);
CGContextStrokePath(context);
CGContextFlush(context);
The key points are
1) CGContextSetLineCap(context, kCGLineCapRound), which makes it round
2) CGContextSetBlendMode(context, kCGBlendModeClear) which clears the context.
I realize this is an older question but I thought I would expand on Eric Reids answer as I was trying to use his example outside of the drawRect method and had to modify it to get it to work with a context I created in a 'touchesMoved' method in a UIView subclass.
I call this method from 'touchesMoved' and pass it the CGPoint of the touch in the view I'm drawing in.
-(void) processEraseAtPoint:(CGPoint)point
{
// setup a context with the size of our canvas view (the canvas view is the UIView instance I'm drawing into)
UIGraphicsBeginImageContext(self.canvasView.bounds.size);
// get a reference to the context we just created
CGContextRef context = UIGraphicsGetCurrentContext();
// draw the image we want to edit into this context (this is the image containing the drawing I want to erase part of)
[self.canvasView.incrementalImage drawAtPoint:CGPointZero];
// set our context options
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetLineWidth(context, self.canvasView.settings.brushDiameter);
CGContextSetBlendMode(context, kCGBlendModeClear);
// make the color clear since we're erasing
CGContextSetStrokeColorWithColor(context, [[UIColor clearColor] CGColor]);
// start our path in this context
CGContextBeginPath(context);
// set our first point
CGContextMoveToPoint(context, lastTouch.x, lastTouch.y);
// draw from our last point to this point
CGContextAddLineToPoint(context, point.x, point.y);
// stroke this path (in this case it's clear so it will erase what's there)
CGContextStrokePath(context);
// set our incrementalImage in the canvasView with the updated image from this context
// Note that in the canvasView 'drawRect' method I am calling
// '[self.incrementalImage drawInRect:rect]', so this new image will get drawn
// in my canvasView when I call 'setNeedsDisplay'
self.canvasView.incrementalImage = UIGraphicsGetImageFromCurrentImageContext();
// cleanup our context
CGContextFlush(context);
UIGraphicsEndImageContext();
// set our last touch point for the next line segment
lastTouch = point;
// update our view
[self.canvasView setNeedsDisplay];
}

Shadow at the top of a Cell UITableCellView

I wondered if anyone knows how to get a shadaow effect like the one in things as per the screenshot. To me it looks like the shadow effect is created by having a shadow at the bottom of the cell above and the top of the cell below.
I can create the one from the cell above using the code below but can't figure out how to do it on the cell underneath as it doesn't get shown it's as if the cells are rendered in reverse order in terms of the z-index.
self.layer.shadowOffset = CGSizeMake(0, 2);
self.layer.shadowColor = [[UIColor blackColor] CGColor];
self.layer.shadowRadius = 2;
self.layer.shadowOpacity = 0.5;
CGFloat top = self.layer.bounds.origin.y;
CGFloat left = self.layer.bounds.origin.x;
CGFloat width = self.layer.bounds.size.width;
CGRect shadowFrame = CGRectMake(left, top, width, 44);
CGPathRef shadowPath = [UIBezierPath bezierPathWithRect:shadowFrame].CGPath;
self.layer.shadowPath = shadowPath;
Any suggestions much appreciated.
Things http://www.purplesmash.com/images/Things.jpg
Just create hollow rectangle while drawing with CoreGraphics (align it exactly that hollow part cover your cell visible view) and set shadow for context - this will save performance for you.
UPDATE:
I've tried this inside my cell drawRect: method
// Creating path which will hold our hollow rectangle
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, CGRectMake(-8.0f, -8.0f, 336.0f, 96.0f));
CGPathAddRect(path, NULL, CGRectMake(-5.0f, 0.0f, 330.0f, 80.0f));
// Saving current graphics context state
CGContextSaveGState(context);
// Configuring shadow
CGContextSetShadowWithColor(context, CGSizeMake(0.0f, 0.0f), 6.0f,
[[UIColor blackColor] CGColor]);
// Adding our path
CGContextAddPath(context, path);
// Configure hollow rectangle fill color
CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0);
// Fill rectangle and keep hollow part transparent
CGContextEOFillPath(context);
// Restore graphics context
CGContextRestoreGState(context);
Of course additional improvement will be pre-calculate CGMutablePathRef path somewhere in initialization or in this method by condition if(path == NULL). Colors can be retained too. If this should be last row of your cell update, than maybe you don't event need to save context state.
You probably need to do this by drawing the shadows as part of the checked cell instead of setting the shadow properties on the surrounding cells.
I'd do it by adding one or two CAGradientLayers as children of the checked cell's contentView.layer.
I have edited this in light of the suggestion from moonlight. I put that code into a method addInnerTopShadow when a cell needs that I call the method. I have added another method addInnerBottomShadow which puts in the shadow at the bottom.
I call these methods in the drawRect method and when I want to change between the states I call the method:
[cell setNeedsDisplay];
This allows me to toggle the state of the cell without doing things like
[self.tableView reloadData];
As the methods suggest I have outer shadow methods that put a shadow on the first and last cells but that's another issue and has been answered many times. I now have my app working exactly how I want. So thanks to Rob and Moonlight.
-(void)addInnerBottomShadow
{
CGContextRef context = UIGraphicsGetCurrentContext();
// Creating path which will hold our hollow rectangle
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, CGRectMake(0, 44, 480, 80));
CGPathAddRect(path, NULL, CGRectMake(0, 54, 480, 96));
// Saving current graphics context state
CGContextSaveGState(context);
// Configuring shadow
CGContextSetShadowWithColor(context, CGSizeMake(0.0f, 0.0f), 6.0f, [[UIColor blackColor] CGColor]);
// Adding our path
CGContextAddPath(context, path);
// Configure hollow rectangle fill color
CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0);
// Fill rectangle and keep hollow part transparent
CGContextEOFillPath(context);
CGContextClipToRect(context, self.bounds);
// Restore graphics context
CGContextRestoreGState(context);
}
-(void)addInnerTopShadow
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, CGRectMake(-8.0f, -8.0f, 336.0f, 96.0f));
CGPathAddRect(path, NULL, CGRectMake(-5.0f, 0.0f, 330.0f, 80.0f));
// Saving current graphics context state
CGContextSaveGState(context);
// Configuring shadow
CGContextSetShadowWithColor(context, CGSizeMake(0.0f, 0.0f), 7.0f, [[UIColor blackColor] CGColor]);
// Adding our path
CGContextAddPath(context, path);
// Configure hollow rectangle fill color
CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0);
// Fill rectangle and keep hollow part transparent
CGContextEOFillPath(context);
CGContextClipToRect(context, self.bounds);
// Restore graphics context
CGContextRestoreGState(context);
}

How to draw a line with a custom style using Core Graphics?

I'm currently drawing a line using Core Graphics. It's really bare bones and simple.
- (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, 300.0f, 600.0f);
CGContextSetLineWidth(c, 25);
CGContextSetLineCap(c, kCGLineCapRound);
CGContextStrokePath(c);
}
This works well. Let's say that we wanted to draw a custom style line. Say we wanted to imitate the style of a crayon for example. And that the designer handed your crayon style images: http://imgur.com/a/N40ig
To do accomplish this effect I think I need to do something like this:
Create a special colored versions of crayonImage1-crayonImage4
Every time you add a line to line you use one of the crayonImages
You alternate the crayonImages every time you draw a point.
Step 1 makes sense. I can use the following method:
- (UIImage *)image:(UIImage *)img withColor:(UIColor *)color {
// begin a new image context, to draw our colored image onto
UIGraphicsBeginImageContext(img.size);
// get a reference to that context we created
CGContextRef context = UIGraphicsGetCurrentContext();
// set the fill color
[color setFill];
// translate/flip the graphics context (for transforming from CG* coords to UI* coords
CGContextTranslateCTM(context, 0, img.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
// set the blend mode to color burn, and the original image
CGContextSetBlendMode(context, kCGBlendModeColorBurn);
CGRect rect = CGRectMake(0, 0, img.size.width, img.size.height);
CGContextDrawImage(context, rect, img.CGImage);
// set a mask that matches the shape of the image, then draw (color burn) a colored rectangle
CGContextClipToMask(context, rect, img.CGImage);
CGContextAddRect(context, rect);
CGContextDrawPath(context,kCGPathFill);
// generate a new UIImage from the graphics context we drew onto
UIImage *coloredImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//return the color-burned image
return coloredImg;
}
I'm unsure how I can complete steps 2 and 3. Is there an API in CoreGraphics for setting an image as the point of line? If so what is it and how can I use it?
Thanks in advance,
-David
Start with the following example: http://www.ifans.com/forums/showthread.php?t=132024
But for brushes, don't draw a line. Simply draw the brush image using CGContextDrawImage.
Basically, you simply draw an image for every touch.

drawRect: isn't working

I want to place some "handles" on a UIView I have on-screen.
So, I'm creating more UIViews, one at each corner of the UIView's frame rectangle, and I simply want to draw a circle that "fills" the rectangle that is the frame of the "handle" UIView.
Here's what I mean:
How I create the "HandleView":
CGPoint upperLeft = CGPointMake([[self viewToMove] frame].origin.x - 5, [[self viewToMove] frame].origin.y - 5);
HandleView *uL = [[HandleView alloc] initWithFrame:CGRectMake(upperLeft.x, upperLeft.y, 10, 10)];
[self setUpperLeftHandle:uL];
[uL release];
[[self view] addSubview:[self upperLeftHandle]];
drawRect: for HandleView:
- (void)drawRect:(CGRect)rect {
// Drawing code
CGContextRef context = UIGraphicsGetCurrentContext();
[[UIColor orangeColor] set];
CGContextFillEllipseInRect(context, [self frame]);
}
What I'm getting is just a set of black rectangles where I place the HandleViews. I'm not sure why they're black, but I can change the color by changing the [HandleView backgroundColor] property. I cannot, though, get anything to DRAW on this view. Calling setNeedsDisplay doesn't seem to make any difference.
Also, the drawRect: method IS being called, so there's a problem with the code there, probably not anywhere else.
It's been a while since I've messed with custom drawing, but I don't remember it being this hard.
What am I missing?
Thanks!!!
Update:
Modified code to this:
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
// Initialization code
[self setBackgroundColor:[UIColor clearColor]];
}
return self;
}
- (void)drawRect:(CGRect)rect {
// Drawing code
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBFillColor(context, 100, 100, 100, 1.0);
CGContextFillEllipseInRect(context, rect);
}
Now, I see the circle, but only where it overlays another view. Where it's just sitting on top of the "background" UIView, I get nothing I can see. Also, even though the color is (100, 100, 100), it shows up white/light-light-gray.
What's the deal?
This might work:
- (void)drawRect:(CGRect)rect {
// Drawing code
[[UIColor orangeColor] setFill];
[[UIBezierPath bezierPathWithOvalInRect:rect] fill];
}
The problem is with the following line:
CGContextFillEllipseInRect(context, [self frame]);
You need to change this to the following:
CGContextFillEllipseInRect(context, [self bounds]);
Origin of frame is the left-top corner location of view in the parent. So, it can be any value within the limits of the size of parent view.
So, while drawing with frame, you will be offsetting Fillellipse rect location which happens to be beyond the visible rect of the handle view.
Hence, you were not able to see anything.
As for the color showing up as white, it's because CGContextSetRGBFillColor() expects values from 0.0 to 1.0 for the color component values (not 0-255). So, by passing 100, you were effectively passing 1.0, which was creating a white color.

Beginner iphone question: drawing a rectangle. What am I doing wrong?

Trying to figure out what I'm doing wrong here. Have tried several things, but I never see that elusive rectangle on the screen. Right now, that's all I want to do -- just draw a single rectangle on the screen.
I'm getting an "invalid context" on everything but the CGContextSetRGBFillColor(). Getting the context after that seems kinda wrong to me, but I'm not at home looking at the examples I was using last night.
Have I messed up something else as well? I really would like to get at least this much done tonight...
- (id)initWithCoder:(NSCoder *)coder
{
CGRect myRect;
CGPoint myPoint;
CGSize mySize;
CGContextRef context;
if((self = [super initWithCoder:coder])) {
NSLog(#"1");
currentColor = [UIColor redColor];
myPoint.x = (CGFloat)100;
myPoint.y = (CGFloat)100;
mySize.width = (CGFloat)50;
mySize.height = (CGFloat)50;
NSLog(#"2");
// UIGraphicsPushContext (context);
NSLog(#"3");
CGContextSetRGBFillColor(context, 1.0, 0.0, 0.0, 1.0);
context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, currentColor.CGColor);
CGContextAddRect(context, myRect);
CGContextFillRect(context, myRect);
}
return self;
}
Thanks,
Sean.
Starting with a View-based template, create a project named Drawer. Add a UIView class to your project. Name it SquareView (.h and .m).
Double-click DrawerViewController.xib to open it in Interface Builder. Change the generic view there to SquareView in the Identity Inspector (command-4) using the Class popup menu. Save and go back to Xcode.
Put this code in the drawRect: method of your SquareView.m file to draw a large, crooked, empty yellow rectangle and a small, green, transparent square:
- (void)drawRect:(CGRect)rect;
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(context, 1.0, 1.0, 0.0, 1.0); // yellow line
CGContextBeginPath(context);
CGContextMoveToPoint(context, 50.0, 50.0); //start point
CGContextAddLineToPoint(context, 250.0, 100.0);
CGContextAddLineToPoint(context, 250.0, 350.0);
CGContextAddLineToPoint(context, 50.0, 350.0); // end path
CGContextClosePath(context); // close path
CGContextSetLineWidth(context, 8.0); // this is set from now on until you explicitly change it
CGContextStrokePath(context); // do actual stroking
CGContextSetRGBFillColor(context, 0.0, 1.0, 0.0, 0.5); // green color, half transparent
CGContextFillRect(context, CGRectMake(20.0, 250.0, 128.0, 128.0)); // a square at the bottom left-hand corner
}
You don't have to call this method for the drawing to happen. Your view controller will tell the view to draw itself at least once when the program launches and the NIB files are activated.
You are not supposed to put CG code in initWithCoder. That message should only be used for INITIALIZATION purpose.
Put your drawing code in:
- (void)drawRect:(CGRect)rect
If you are subclassing a UIView...