0

I have this code so far:

CGPoint midLeft = CGPointMake(0, additionalHeight);
    CGPoint bottomCenter = CGPointMake(self.bounds.size.width / 2, self.bounds.size.height);
    CGPoint midRight = CGPointMake(self.bounds.size.width, additionalHeight);
    CGPoint topRight = CGPointMake(self.bounds.size.width, 0);
    CGPoint topLeft = CGPointMake(0, 0);
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    

    CGContextMoveToPoint(context, midLeft.x, midLeft.y);
    CGContextAddLineToPoint(context, midRight.x, midRight.y);
    CGContextAddLineToPoint(context, topRight.x, topRight.y);
    CGContextAddLineToPoint(context, topLeft.x, topLeft.y);

    CGContextClosePath(context);

Right now, it just draws me a rectangle, but I want it to draw me an arc, which reaches down to bottomCenter, like the shape at the top of this image:

enter image description here

I've tried CGContextAddArc and AddArcToPoint, and followed tutorials, but I can't figure out how to draw this kind of arc. Any help is appreciated.

Andrew
  • 15,935
  • 28
  • 121
  • 203

2 Answers2

5

Check out this blog post, it covers arcs and paths. The result is almost the same as what you're aiming for.

My recommendation is to do his whole Core Graphics 101 series, it's really good.

You could also use UIBezierPath instead. With addQuadCurveToPoint:controlPoint: you can easily create a arc-like shape.

I havent tested the code below, but it should create something like this: enter image description here

UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(0, 10)];
[path addQuadCurveToPoint:CGPointMake(200, 10) controlPoint:CGPointMake(100, 5)];
[path addLineToPoint:CGPointMake(200, 0)];
[path addLineToPoint:CGPointMake(0, 0)];
[path closePath];

CGContextAddPath(context, path.CGPath);
[[UIColor redColor] set];
CGContextFillPath(context);

Hope this is to any help.

Paul.s
  • 38,494
  • 5
  • 70
  • 88
hellozimi
  • 1,858
  • 19
  • 21
0

You can do this by cleverly clipping a circle on the top of the rectangle. Below is some untested code that should be what you need. In this case, myRect would be the large rectangle that you wan't to draw on. You might want to adjust the multiplier to get the "shine" to look properly.

    //clip the rectangle so we don't draw anything above it
    CGContextAddPath(ctx, myBezierPath.CGPath);
    CGContextClip(ctx);

    //create a multiplier so the curve looks wide
    CGFloat circleMultiplier = 2.0;
    CGRect largeCircleRect = CGRectMake(0, 0, CGRectGetWidth(myRect) * circleMultiplier,  CGRectGetHeight(myRect) * circleMultiplier);

    CGFloat upSpace = (CGRectGetHeight(largeCircleRect) - CGRectGetHeight(myRect)) + 40.0; //40 pts showing at the top
    CGFloat sideSpace = (CGRectGetWidth(largeCircleRect) - CGRectGetWidth(myRect)) / 2.0; //center it horizontally
    largeCircleRect.origin.y -= upSpace;
    largeCircleRect.origin.x -= sideSpace;

    CGContextAddEllipseInRect(ctx, largeCircleRect);
    CGContextFillPath(ctx);
Vinnie
  • 1,670
  • 14
  • 16