Reputation: 8782
EDIT: there are a few other questions on SO but they all help you draw either a circle or an arc within a UIView. I need a sector which is also as a UIImage and not UIView.
iOS programmatically create UIImage of a circle sector given the angle and radius
I am trying to create a UIImage of a circle sector given the angle and radius. The end result should be a mono-colored version of this image. I don't need the gradient which this image has. A single color is fine.
I need to create many of such segments with different colors.
Here's what I have tried so far but it ends up looking like this which I have no clue:
Call:
[self getSegmentImageOfRadius:177.5 andAngleRadians:0.63]
Method:
-(UIImage*)getSegmentImageOfRadius:(CGFloat)radius andAngleRadians:(CGFloat)angleRadians{
UIBezierPath *sector = [UIBezierPath
bezierPathWithArcCenter:CGPointMake(0, 0) radius:radius startAngle:0 endAngle:angleRadians clockwise:YES];
UIGraphicsBeginImageContext(CGSizeMake(radius,radius));
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [UIColor greenColor].CGColor);
[sector fill];
UIImage *mage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return mage;
}
Upvotes: 1
Views: 1296
Reputation: 598
I have created the circle view with radius, start angle and end angle.
240
|
180 ---|--- 0 - Start Angle point in my code.
|
90
#define DEGREES_TO_RADIANS(d) ((d) * 0.0174532925199432958f)
// Sample image view.
UIImageView *circleView = [[UIImageView alloc] initWithFrame:CGRectMake(50.0f, 382.0f, 120.0f,120.0f)];
circleView.image = [self getSegmentImageOfRadius:30 startAngle:90 andEndAngle:180 withFrame:circleView.frame.size];
[self.view addSubview:circleView];
-(UIImage*)getSegmentImageOfRadius:(CGFloat)radius startAngle:(CGFloat)startAngle andEndAngle:(CGFloat)endAngle withFrame :(CGSize) size {
// Create View with frame of radius
UIView *circleView = [[UIView alloc] initWithFrame:CGRectMake(radius, radius, radius*2, radius*2)];
// Create new object for UIBezierPath
UIBezierPath *bezierPath = [UIBezierPath bezierPath];
// Find the center point of the view.
CGPoint center = CGPointMake(CGRectGetMidX(circleView.frame), CGRectGetMidY(circleView.frame));
// Add the arc with given properties.
[bezierPath addArcWithCenter:center radius:radius startAngle:DEGREES_TO_RADIANS(startAngle) endAngle: DEGREES_TO_RADIANS(endAngle) clockwise:YES];
// Add the shape layer.
CAShapeLayer *progressLayer = [[CAShapeLayer alloc] init];
[progressLayer setPath:bezierPath.CGPath];
[progressLayer setStrokeColor:[UIColor blueColor].CGColor];
[progressLayer setFillColor:[UIColor clearColor].CGColor];
[progressLayer setLineWidth:circleView.frame.size.width];
[circleView.layer addSublayer:progressLayer];
// Convert and render UIView into UIImage.
UIGraphicsBeginImageContext(size);
CGContextRef context = UIGraphicsGetCurrentContext();
[circleView.layer renderInContext:context];
UIImage *saveImage;
saveImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return saveImage;
}
Refer : 2DDrawing
Upvotes: 1
Reputation: 1192
Try this..
create an imageView with width almost 190 (based on your requirement)
#define pi 3.14159265359
#define DEGREES_TO_RADIANS(degrees) ((pi * degrees) / 180)
In viewDidLoad
UIImage *image = [self getSegmentImageOfRadius:_imageView.frame.size.width/2 startAngle:160 andEndAngle:200];
_imageView.image = image;
Change the method as below
-(UIImage*)getSegmentImageOfRadius:(CGFloat)radius startAngle:(CGFloat)startAngle andEndAngle:(CGFloat)endAngle
{
CGPoint center = CGPointMake(_imageView.frame.size.width/2, _imageView.frame.size.height/2);
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:center];
[path addArcWithCenter:center radius:radius startAngle:DEGREES_TO_RADIANS(startAngle) endAngle:DEGREES_TO_RADIANS(endAngle) clockwise:YES];
[path closePath];
CAShapeLayer *layer = [CAShapeLayer layer];
layer.frame = _imageView.bounds;
layer.path = path.CGPath;
layer.fillColor = [UIColor redColor].CGColor;
UIGraphicsBeginImageContextWithOptions(layer.frame.size, NO, 0);
[layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return outputImage;
}
If you doesn't need as an image, you can add shape to your view's layer as shown below
CGPoint center = CGPointMake(self.view.frame.size.width/2, self.view.frame.size.height/2);
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:center];
[path addArcWithCenter:center radius:radius startAngle:DEGREES_TO_RADIANS(startAngle) endAngle:DEGREES_TO_RADIANS(endAngle) clockwise:YES];
[path closePath];
CAShapeLayer *layer = [CAShapeLayer layer];
layer.path = path.CGPath;
layer.fillColor = [UIColor redColor].CGColor;
[self.view.layer addSublayer:layer];
Upvotes: 2
Reputation: 598
You method is working fine. But, I felt your input are wrong to your function.
// 1 - Test
UIImageView *sample = [[UIImageView alloc] initWithFrame:CGRectMake(20.0f, 122.0f, 50.0f,50.0f)];
sample.image = [self getSegmentImageOfRadius:50 andAngleRadians:50];
[self.view addSubview:sample];
// Add this funciton to your view controller
-(UIImage*)getSegmentImageOfRadius:(CGFloat)radius andAngleRadians:(CGFloat)angleRadians{
UIBezierPath *sector = [UIBezierPath
bezierPathWithArcCenter:CGPointMake(0, 0) radius:radius startAngle:0 endAngle:angleRadians clockwise:YES];
UIGraphicsBeginImageContext(CGSizeMake(radius,radius));
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [UIColor greenColor].CGColor); // Fill color.
[sector fill];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); // Create image form curent context.
UIGraphicsEndImageContext();
return image;
}
Output :
Upvotes: 0