DrawRect fits 4" screen, but runs off the bottom of 3.5" - ios

Ive Created a DrawRect that fits the screen perfectly when running on a 4" screen. but when applied to a 3.5" the size changes and cant be constrained. Is there a way i can maintain its shape on both? Below is my code:
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect rrect = CGRectMake(20, 30, 280, 515);
CGFloat radius = 7;
CGFloat minx = CGRectGetMinX(rrect), midx = CGRectGetMidX(rrect), maxx = CGRectGetMaxX(rrect);
CGFloat miny = CGRectGetMinY(rrect), midy = CGRectGetMidY(rrect), maxy = CGRectGetMaxY(rrect);
// Start at 1
CGContextMoveToPoint(context, minx, midy);
// Add an arc through 2 to 3
CGContextAddArcToPoint(context, minx, miny, midx, miny, radius);
// Add an arc through 4 to 5
CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius);
// Add an arc through 6 to 7
CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius);
// Add an arc through 8 to 9
CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius);
// Close the path
CGContextClosePath(context);
CGContextSetStrokeColorWithColor(context, [[UIColor whiteColor] CGColor]);
CGContextSetRGBFillColor(context, 255, 255, 255, 1.0);
// Fill & stroke the path
CGContextDrawPath(context, kCGPathFillStroke);
}

Related

Core Graphics drawing a square result in rectangle

I am trying to draw a square in my context, but it results in a rectangle with a short and longer side. (in my ipad retina simulator)
This is part of the drawRect method of my view object:
CGContextRef context = UIGraphicsGetCurrentContext();
CGFloat minx = 0;
CGFloat maxx = 45 - 1;
CGFloat miny = 0;
CGFloat maxy = 45 - 1;
CGContextSetLineWidth(context, 1.0);
CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
CGContextMoveToPoint(context, minx, maxy);
CGContextAddLineToPoint(context, minx, miny);
CGContextAddLineToPoint(context, maxx, miny);
CGContextStrokePath(context);
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
CGContextMoveToPoint(context, maxx, miny);
CGContextAddLineToPoint(context, maxx, maxy);
CGContextAddLineToPoint(context, minx, maxy);
CGContextStrokePath(context);
What am I doing wrong? Do I need to set an aspect ratio or something?
Edit:
I found out that
CGContextScaleCTM(context, 1, 0.75f);
makes the result square again, but the end result is not spot on.
Does anybody know why I need to correct the vertical scale?
Found it....
Turns out I was modifying the views rect elsewhere.
Disabled that, and now my squares are square again.
Thanks for the hint Ismael !!

Is Point Inside Rounded Rectangle?

I have this code to draw rounded rectangles:
void ContextAddRoundedRect(CGContextRef ctx, CGRect rect, CGFloat radius) {
CGFloat minX = CGRectGetMinX(rect);
CGFloat maxX = CGRectGetMaxX(rect);
CGFloat minY = CGRectGetMinY(rect);
CGFloat maxY = CGRectGetMaxY(rect);
CGContextMoveToPoint(ctx, minX + radius, minY);
CGContextAddArcToPoint(ctx, maxX, minY, maxX, minY + radius, radius);
CGContextAddArcToPoint(ctx, maxX, maxY, maxX - radius, maxY, radius);
CGContextAddArcToPoint(ctx, minX, maxY, minX, maxY - radius, radius);
CGContextAddArcToPoint(ctx, minX, minY, minX + radius, minY, radius);
}
how can I figure out if a given CGPoint is inside my rect, considering the rounded corners?
Instead of building it directly into the CGContextRef like this, you can build it instead as a UIBezierPath, and then use -[UIBezierPath containsPoint:].
When you're ready to actually render your path into the context, you can do so via:
CGContextAddPath(ctx, [myBezierPath CGPath]);

UIView drawRect: is it possible to stroke inside a path?

With core graphics, is it possible to stroke the inside of a path? As opposed to the line weight being drawn half on the outside and half on the inside of a stroked path?
The reason being it would be easier to control the visible thickness of the stroke if say part of a view is on the screen edge and part is not. The part on the screen edge gets cut off, while the view edge that is fully on screen looks thicker (as both sides if the stroke are visible).
Clip to the path before you stroke it.
This draws no stroke:
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, [UIColor darkGrayColor].CGColor);
CGContextSetLineWidth(context, 14);
CGRect rrect = CGRectMake(CGRectGetMinX(rect), CGRectGetMinY(rect), CGRectGetWidth(rect), CGRectGetHeight(rect));
CGFloat radius = 30;
CGFloat minx = CGRectGetMinX(rrect), midx = CGRectGetMidX(rrect), maxx = CGRectGetMaxX(rrect);
CGFloat miny = CGRectGetMinY(rrect), midy = CGRectGetMidY(rrect), maxy = CGRectGetMaxY(rrect);
CGContextMoveToPoint(context, minx, midy);
CGContextAddArcToPoint(context, minx, miny, midx, miny, radius);
CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius);
CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius);
CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius);
CGContextClosePath(context);
CGContextClip(context);
CGContextDrawPath(context, kCGPathStroke);
}
EDIT: This is what worked (according to the correct answer):
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, [UIColor darkGrayColor].CGColor);
CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);
CGContextSetLineWidth(context, 14);
CGRect pathRect = CGRectMake(10, 10, rect.size.width -20, rect.size.height -20);
CGPathRef path = [UIBezierPath bezierPathWithRoundedRect:pathRect cornerRadius:20].CGPath;
CGContextAddPath(context, path);
CGContextClip(context);
CGContextAddPath(context, path);
CGContextDrawPath(context, kCGPathEOFillStroke);
}

Clear remnants of drawRect() in custom UIControl

I create a custom slider with using subclass of UIControl. I draw my background and a button in drawRect() but when I redraw my button, there are remnants of previous draw left.
How can I clear this?
I try to track memory leaks with instruments but I haven't found any leaks. My code is:
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGFloat radius = 10;
// Make sure corner radius isn't larger than half the shorter side
if (radius > self.bounds.size.width/2.0) radius = self.bounds.size.width/2.0;
if (radius > self.bounds.size.height/2.0) radius = self.bounds.size.height/2.0;
CGFloat minx = CGRectGetMinX(self.bounds);
CGFloat midx = CGRectGetMidX(self.bounds);
CGFloat maxx = CGRectGetMaxX(self.bounds);
CGFloat miny = CGRectGetMinY(self.bounds);
CGFloat maxy = CGRectGetMaxY(self.bounds);
CGContextMoveToPoint(context, maxx, miny);
CGContextAddArcToPoint(context, minx, miny+ 30, minx, miny+150, radius);
CGContextAddArcToPoint(context, minx, maxy-30, minx+30, maxy, radius);
CGContextAddLineToPoint (context, maxx, maxy);
CGContextClosePath(context);
CGContextSetRGBFillColor(context,
0.0, 0.0, 0.0, 0.2 );
CGContextSetRGBStrokeColor( context,
0.7, 0.7, 0.7, 0.4 );
CGContextDrawPath(context, kCGPathFill);
CGContextSetLineWidth(context, 10);
CGContextSetLineCap(context, kCGLineCapRound);
CGContextMoveToPoint(context, midx, miny+ 80);
CGContextAddLineToPoint(context, midx, maxy-50);
CGContextStrokePath(context);
[self drawButton: _buttonRect inContext:context];
}
and the drawButton() function:
- (void)drawButton:(CGRect)rect inContext:(CGContextRef) context{
UIGraphicsPushContext(context);
CGFloat radius = 7;
CGFloat minx = CGRectGetMinX(rect);
CGFloat midx = CGRectGetMidX(rect);
CGFloat maxx = CGRectGetMaxX(rect);
CGFloat miny = CGRectGetMinY(rect);
CGFloat midy = CGRectGetMidY(rect);
CGFloat maxy = CGRectGetMaxY(rect);
CGContextMoveToPoint(context, minx, midy);
CGContextAddArcToPoint(context, minx, miny, midx, miny, radius);
CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius);
CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius);
CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius);
CGContextClosePath(context);
CGContextSetRGBFillColor(context,
1.0, 1.0, 1.0, 1.0 );
CGContextDrawPath(context, kCGPathFill);
CGContextSetRGBStrokeColor(context,
1.0, 0.0, 0.0, 1.0 );
//Gradient related variables
size_t locationCount = 3;
CGFloat locationList[] = {0.0,0.5,1.0};
CGFloat colorList[] = {
0.0, 0.0, 0.0, 1.0,
0.5, 0.5, 0.5, 1.0,
1.0, 1.0, 1.0, 1.0
};
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colorList,
locationList, locationCount);
//Paint a linear gradient
CGPoint startPoint, endPoint;
startPoint.x = midx;
startPoint.y = midy-2.5;
endPoint.x = midx;
endPoint.y = midy+2.5;
CGContextSaveGState(context);
CGContextAddEllipseInRect(context, CGRectMake(midx-2.5, midy-2.5, 5, 5));
CGContextClosePath(context);
CGContextClip(context);
CGContextDrawLinearGradient (context, gradient, startPoint, endPoint, kCGGradientDrawsAfterEndLocation);
CGContextRestoreGState(context);
UIGraphicsPopContext();
}
I tried a lot of things but now I have no idea anymore. Thanks.

How to clip the rectangle around the circle when drawing with quartz2d?

I made of subclass of UIView called Bubble using which i want to draw a solid circle.Here is the drawRect: rect method
- (void)drawRect:(CGRect)rect
{
// Drawing code
CGContextRef ctx = UIGraphicsGetCurrentContext();
// Drawing with a white stroke color
CGContextSetRGBStrokeColor(ctx, 1.0, 1.0, 1.0, 1.0);
// And draw with a blue fill color
CGContextSetRGBFillColor(ctx, 0.0, 0.0, 1.0, 1.0);
// Draw them with a 2.0 stroke width so they are a bit more visible.
CGContextSetLineWidth(ctx, 2.0);
CGRect rrect = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, self.bounds.size.width, self.bounds.size.height);
CGFloat radius = 30.0;
CGFloat minx = CGRectGetMinX(rrect), midx = CGRectGetMidX(rrect), maxx = CGRectGetMaxX(rrect);
CGFloat miny = CGRectGetMinY(rrect), midy = CGRectGetMidY(rrect), maxy = CGRectGetMaxY(rrect);
// Start at 1
CGContextMoveToPoint(ctx, minx, midy);
// Add an arc through 2 to 3
CGContextAddArcToPoint(ctx, minx, miny, midx, miny, radius);
// Add an arc through 4 to 5
CGContextAddArcToPoint(ctx, maxx, miny, maxx, midy, radius);
// Add an arc through 6 to 7
CGContextAddArcToPoint(ctx, maxx, maxy, midx, maxy, radius);
// Add an arc through 8 to 9
CGContextAddArcToPoint(ctx, minx, maxy, minx, midy, radius);
// Close the path
CGContextClosePath(ctx);
// Fill & stroke the path
CGContextDrawPath(ctx, kCGPathFillStroke);
}
I have taken the code from the apple sample Quartzdemo.
My problem is i am drawing circle inside a rectangle,but still i see the corners of the rectangle drawn.
How to clip them so that i see only circle? please help. i am new to quartz 2d
Here is how i call it in my viewDidLoad of my controller
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:0.5];
Bubble *bub = [[Bubble alloc]initWithFrame:CGRectMake(210.0, 90.0, 60.0, 60.0)];
[self.view addSubview:bub];
[bub release];
}
Put this is viewDidLoad
bub.backgroundColor = [UIColor clearColor];

Resources