UIView rounded corners Question - iphone

Whats wrong with this code?
-(void) drawRect:(CGRect) rect {
CGContextRef c = UIGraphicsGetCurrentContext();
if (c != nil) {
CGContextSetFillColorWithColor(c, self.cornerColor.CGColor);
[self drawRoundedCornersInRect:self.bounds inContext:c];
CGContextFillPath(c);
}
}
-(void) drawCornerInContext:(CGContextRef)c cornerX:(int) x cornerY:(int) y
arcEndX:(int) endX arcEndY:(int) endY {
CGContextMoveToPoint(c, x, endY);
CGContextAddArcToPoint(c, x, y, endX, y, radius);
CGContextAddLineToPoint(c, x, y);
CGContextAddLineToPoint(c, x, endY);
}
-(void) drawRoundedCornersInRect:(CGRect) rect inContext:(CGContextRef) c {
int x_left = rect.origin.x;
int x_left_center = rect.origin.x + radius;
int x_right_center = rect.origin.x + rect.size.width - radius;
int x_right = rect.origin.x + rect.size.width;
int y_top = rect.origin.y;
int y_top_center = rect.origin.y + radius;
int y_bottom_center = rect.origin.y + rect.size.height - radius;
int y_bottom = rect.origin.y + rect.size.height;
if (roundUpperLeft) {
[self drawCornerInContext:c cornerX: x_left cornerY: y_top
arcEndX: x_left_center arcEndY: y_top_center];
}
if (roundUpperRight) {
[self drawCornerInContext:c cornerX: x_right cornerY: y_top
arcEndX: x_right_center arcEndY: y_top_center];
}
if (roundLowerRight) {
[self drawCornerInContext:c cornerX: x_right cornerY: y_bottom
arcEndX: x_right_center arcEndY: y_bottom_center];
}
if (roundLowerLeft) {
[self drawCornerInContext:c cornerX: x_left cornerY: y_bottom
arcEndX: x_left_center arcEndY: y_bottom_center];
}
}
No errors, No warnings ... but the round corners don't work at all. I found this code here.

You need to begin a path, and close it when you're done. Your 2nd call to CGContextAddLineToPoint messes things up I think. Here's a snippet that works. Study it and enhance it to support your multiple cases (it seems that you want to be able to round only some corners, and not necessarily all of them...)
void addRoundedRect(CGContextRef ctx, CGRect rect, float cornerRadius) {
if (cornerRadius <= 2.0) {
CGContextAddRect(ctx, rect);
} else {
float x_left = rect.origin.x;
float x_left_center = x_left + cornerRadius;
float x_right_center = x_left + rect.size.width - cornerRadius;
float x_right = x_left + rect.size.width;
float y_top = rect.origin.y;
float y_top_center = y_top + cornerRadius;
float y_bottom_center = y_top + rect.size.height - cornerRadius;
float y_bottom = y_top + rect.size.height;
/* Begin path */
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, x_left, y_top_center);
/* First corner */
CGContextAddArcToPoint(ctx, x_left, y_top, x_left_center, y_top, cornerRadius);
CGContextAddLineToPoint(ctx, x_right_center, y_top);
/* Second corner */
CGContextAddArcToPoint(ctx, x_right, y_top, x_right, y_top_center, cornerRadius);
CGContextAddLineToPoint(ctx, x_right, y_bottom_center);
/* Third corner */
CGContextAddArcToPoint(ctx, x_right, y_bottom, x_right_center, y_bottom, cornerRadius);
CGContextAddLineToPoint(ctx, x_left_center, y_bottom);
/* Fourth corner */
CGContextAddArcToPoint(ctx, x_left, y_bottom, x_left, y_bottom_center, cornerRadius);
CGContextAddLineToPoint(ctx, x_left, y_top_center);
/* Done */
CGContextClosePath(ctx);
}
}

I use this: [view.layer setCornerRadius:7];. It sets the corner radius using the UIView's CALayer backer.

Related

How to draw dots in a semi - circle pattern

How can I draw dots in semi circular pattern in iphone programmatically?
I did using the below code
CGContextRef ctx = UIGraphicsGetCurrentContext();
float angle = 0;
float centerX = self.frame.size.width/2;
float centerY = self.frame.size.width/2;
float startX = 0.0;
float startY = 0.0;
for (int i = 0; i < 8 ; i++) {
startX = centerX + cos(angle) * (radius + 50) - 5 ;
startY = centerY + sin(angle) * (radius + 50 ) - 5;
CGContextFillEllipseInRect(ctx, CGRectMake(startX, startY, 5, 5));
[[UIColor blackColor] setStroke];
angle-= M_PI/7;
}
you can like this way Quartz_2D:-
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 20.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);
}
check out bellow all drawing examples :-
http://www.techotopia.com/index.php/An_iOS_5_iPhone_Graphics_Drawing_Tutorial_using_Quartz_2D

How can I create a part of a filled circle using Core Graphics/Quartz

I have made a subclass of UIView and I am trying to draw part of a circle in my drawRect method.
I have tried using bezierPathWithArcCenter and filling it but that only result in a pie shape (image 3) and that's not what i'm after. I want to draw what you see in image 1 and 2.
Maybe I can clip a full circle somehow? The area around the circle needs to be transparent.
TompaLompas answer pointed me in the right direction (with the arc drawing part). However the complete solution and answer is like this:
#define DEGREES_TO_RADIANS(degrees) ((M_PI * degrees)/ 180)
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
CGContextRef ctx = UIGraphicsGetCurrentContext();
int radius = self.frame.size.width / 2;
CGPoint center = CGPointMake(self.frame.size.width / 2, self.frame.size.height / 2);
//Image 2
CGContextSetFillColorWithColor(ctx, [UIColor redColor].CGColor);
CGContextAddArc(ctx, center.x, center.y, radius, DEGREES_TO_RADIANS(225), DEGREES_TO_RADIANS(315), NO);
CGContextDrawPath(ctx, kCGPathFill);
}
try overriding drawRect with this:
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
CGContextRef context = UIGraphicsGetCurrentContext();
float radius = 50.0f;
float x_left = rect.origin.x;
float x_left_center = x_left + radius;
float y_top = rect.origin.y;
float y_top_center = y_top + radius;
/* Begin path */
CGFloat white[4] = {0.0f, 204.0f/255.0f, 1.0f, 0.8f};
CGContextSetFillColor(context, white);
CGContextSetLineWidth(context, 1.0);
CGContextBeginPath(context);
CGContextMoveToPoint(context, x_left, y_top_center);
CGContextAddArcToPoint(context, x_left, y_top, x_left_center, y_top, radius);
CGContextAddLineToPoint(context,x_left, y_top + radius);
CGContextFillPath(context);
}
It will draw a rotated image number 2

How to create Hexagon in iPhone/iPad

I want to make UIView which is originally rectangular to Hexagon shape to be used in my application.
Please help me something on this.
Thanks in advance.
Subclass UView and override drawRect to draw a hexagon like so:
- (void)drawRect:(CGRect)rect
{
float polySize = 60; // change this
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGAffineTransform t0 = CGContextGetCTM(context);
t0 = CGAffineTransformInvert(t0);
CGContextConcatCTM(context, t0);
//Begin drawing setup
CGContextBeginPath(context);
CGContextSetRGBStrokeColor(context, 0, 0, 0, 1);
CGContextSetLineWidth(context, 2.0);
CGPoint center;
//Start drawing polygon
center = CGPointMake(160, 90.0);
CGContextMoveToPoint(context, center.x, center.y + polySize);
for(int i = 1; i < 6; ++i)
{
CGFloat x = polySize * sinf(i * 2.0 * M_PI / 6);
CGFloat y = polySize * cosf(i * 2.0 * M_PI / 6);
CGContextAddLineToPoint(context, center.x + x, center.y + y);
}
//Finish Drawing
CGContextClosePath(context);
CGContextDrawPath(context, kCGPathStroke);
CGContextRestoreGState(context);
}
You can create a subclass of UIView and in it's -(void)drawRect: method draw a hexagon. Or Use UIImageView with image of hexagon

UIControl for a Needle Gauge aka Google O Meter

For those times when a UISlider just isn't fun enough I was thinking I'd work up a custom UIControl to do something similar to a Google O Meter from the google chart API on iOS.
Here's an example of what I'm talking about visually. My goal would be to enable touch manipulation of the needle and easy customization of the range labels and coloring gradients. The Google Charts API is a great inspiration:
Before I re-invent the wheel is anyone aware of an existing effort I could leverage good sample code with something like this or project I could contribute too?
Thanks for any pointers.
I have implemented a GaugeView as a child of UIView and added the code to draw the gauge in the drawRect method. Nothing fancy but may be helpful to start
- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
CGRect parentViewBounds = self.bounds;
CGFloat x = CGRectGetWidth(parentViewBounds)/2;
CGFloat y = CGRectGetHeight(parentViewBounds);
CGFloat radius = y;
CGFloat percent_angle = _progress * M_PI;
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextBeginPath(ctx);
// Add path
CGFloat m2_x = radius * (1.0 - 0.9*cos(percent_angle));
CGFloat m2_y = radius * (1.0 - 0.9*sin(percent_angle));
CGContextBeginPath(ctx);
CGContextAddArc(ctx, x, y, radius, M_PI, 0, 0);
CGContextAddLineToPoint(ctx, x + 0.1*radius, y);
CGContextAddArc(ctx, x, y, 0.1*radius, 0, M_PI, 1);
CGContextClosePath(ctx);
CGContextSetFillColorWithColor(ctx,[UIColor whiteColor].CGColor);
CGContextFillPath(ctx);
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, m2_x, m2_y);
CGContextAddArc(ctx, x, y, 0.9*radius, M_PI + percent_angle, M_PI, 1);
CGContextAddLineToPoint(ctx, 0.8*radius, y);
CGContextSetStrokeColorWithColor(ctx,self.fillColor.CGColor);
CGContextAddArc(ctx, x, y, 0.2*radius, M_PI, M_PI + percent_angle, 0);
CGContextClosePath(ctx);
CGContextStrokePath(ctx);
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, m2_x, m2_y);
CGContextSetFillColorWithColor(ctx,self.fillColor.CGColor);
CGContextAddArc(ctx, x, y, 0.9*radius, M_PI + percent_angle, M_PI, 1);
CGContextAddLineToPoint(ctx, 0.8*radius, y);
CGContextAddArc(ctx, x, y, 0.2*radius, M_PI, M_PI + percent_angle, 0);
CGContextClosePath(ctx);
CGContextFillPath(ctx);
/* CGContextBeginPath(ctx);
CGContextAddArc(ctx, x, y, radius, M_PI, 0, 0);
CGContextAddLineToPoint(ctx, x + 0.1*radius, y);
CGContextAddArc(ctx, x, y, 0.1*radius, 0, M_PI, 1);
CGContextClosePath(ctx);
CGContextSetStrokeColorWithColor(ctx,[self.strokeColor CGColor]);
CGContextStrokePath(ctx);*/
for(int i = 0; i < 100; i++)
{
CGFloat angle =M_PI * 0.01 * i;
CGFloat l1_x = radius * (1.0 - 0.98*cos(angle));
CGFloat l1_y = radius * (1.0 - 0.98*sin(angle));
if(i%10 == 0)
{
l1_x = radius * (1.0 - 0.9*cos(angle));
l1_y = radius * (1.0 - 0.9*sin(angle));
}
else if(i%5 == 0)
{
l1_x = radius * (1.0 - 0.95*cos(angle));
l1_y = radius * (1.0 - 0.95*sin(angle));
}
CGFloat l2_x = radius * (1.0 - cos(angle));
CGFloat l2_y = radius * (1.0 - sin(angle));
CGContextMoveToPoint(ctx, l1_x, l1_y);
CGContextSetLineWidth(ctx, 1.0);
CGContextAddLineToPoint(ctx, l2_x, l2_y);
CGContextSetStrokeColorWithColor(ctx,[self.strokeColor CGColor]);
CGContextStrokePath(ctx);
}
CGFloat n1_x = radius * (1.0 - 0.1*cos(percent_angle));
CGFloat n1_y = radius * (1.0 - 0.1*sin(percent_angle));
CGFloat n2_x = radius * (1.0 - cos(percent_angle));
CGFloat n2_y = radius * (1.0 - sin(percent_angle));
CGContextMoveToPoint(ctx, n1_x, n1_y);
CGContextSetLineWidth(ctx, 4.0);
CGContextAddLineToPoint(ctx, n2_x, n2_y);
CGContextSetStrokeColorWithColor(ctx,[self.needleColor CGColor]);
CGContextStrokePath(ctx);
}

How to crop images in iPhone SDK?

I want to allow a user to select pixels on the screen and create a new image from the pixels created. Is there a specific class for this or would I need to do this all my self?
you should have a look at http://www.hive05.com/2008/11/crop-an-image-using-the-iphone-sdk/
- (UIImage*)getCroppedImage
{
CGRect rect = self.cropView.frame;
CGRect drawRect = [self cropRectForFrame:rect];
UIImage *croppedImage = [self imageByCropping:self.image toRect:drawRect];
return croppedImage;
}
- (UIImage *)imageByCropping:(UIImage *)image toRect:(CGRect)rect
{
if (UIGraphicsBeginImageContextWithOptions)
{
UIGraphicsBeginImageContextWithOptions(rect.size,
/* opaque */ NO,
/* scaling factor */ 0.0);
}
else
{
UIGraphicsBeginImageContext(rect.size);
}
// stick to methods on UIImage so that orientation etc. are automatically
// dealt with for us
[image drawAtPoint:CGPointMake(-rect.origin.x, -rect.origin.y)];
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}
-(CGRect)cropRectForFrame:(CGRect)frame
{
NSAssert(self.contentMode == UIViewContentModeScaleAspectFit, #"content mode must be aspect fit");
CGFloat widthScale = self.bounds.size.width / self.image.size.width;
CGFloat heightScale = self.bounds.size.height / self.image.size.height;
float x, y, w, h, offset;
if (widthScale<heightScale) {
offset = (self.bounds.size.height - (self.image.size.height*widthScale))/2;
x = frame.origin.x / widthScale;
y = (frame.origin.y-offset) / widthScale;
w = frame.size.width / widthScale;
h = frame.size.height / widthScale;
} else {
offset = (self.bounds.size.width - (self.image.size.width*heightScale))/2;
x = (frame.origin.x-offset) / heightScale;
y = frame.origin.y / heightScale;
w = frame.size.width / heightScale;
h = frame.size.height / heightScale;
}
return CGRectMake(x, y, w, h);
}