iPhone - Stroking a path does not work - iphone

I have these methods into a MKOverlayView subclass, and I do not understand why filling a path works, and why stroking that same path doesn't work...
- (id) init {
if (!(self = [super init])) return nil;
self.opaque = NO; // If not set, just black squares are drawn
return self;
}
- (void) drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context {
// CGRect rects[2] = {[self rectForMapRect:mapRect], [self rectForMapRect:self.country.boundingMapRect]};
// CGContextClipToRects(context, rects, 2);
CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 1.0);
CGContextSetRGBFillColor(context, 1.0, 0.0, 1.0, 0.9);
CGContextSetLineWidth(context, 1.0);
for (MKPolygon* poly in self.polygons) {
CGPoint origin = [self pointForMapPoint:poly.points[0]];
CGContextMoveToPoint(context, origin.x, origin.y);
for (int i=1; i<poly.pointCount; i++) {
CGPoint point = [self pointForMapPoint:poly.points[i]];
CGContextAddLineToPoint(context, point.x, point.y);
}
//CGContextFillPath(context);
CGContextStrokePath(context);
}
}
-(BOOL)canDrawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale {
return YES;
}

How zoomed out are you? It's possible that your stroke is working; it just doesn't show up because it's too thin. Try setting your line width to 1.0 / zoomScale (or, more generally, desiredLineWidth * (1.0 / zoomScale)).
(Disclaimer: I've never actually used MapKit, so you may need to use zoomScale as it is; based on my reading of the documentation, I would try 1.0 / zoomScale first.)

Related

Add eraser tool after draw paint

I have paint app. When i click button it launch paint view than user can paint. After i come back then click button the paintview won't reset. How can i reset a view in button click after draw pain.
code:
- (BOOL) initContext:(CGSize)size {
int bitmapByteCount;
int bitmapBytesPerRow;
// Declare the number of bytes per row. Each pixel in the bitmap in this
// example is represented by 4 bytes; 8 bits each of red, green, blue, and
// alpha.
bitmapBytesPerRow = (size.width * 4);
bitmapByteCount = (bitmapBytesPerRow * size.height);
// Allocate memory for image data. This is the destination in memory
// where any drawing to the bitmap context will be rendered.
cacheBitmap = malloc( bitmapByteCount );
if (cacheBitmap == NULL){
return NO;
}
cacheContext = CGBitmapContextCreate (cacheBitmap, size.width, size.height, 8, bitmapBytesPerRow, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipFirst);
return YES;
}
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
[self drawToCache:touch];
[self setNeedsDisplay];
}
- (void) drawToCache:(UITouch*)touch {
hue += 0.005;
if(hue > 1.0) hue = 0.0;
UIColor *color = [UIColor colorWithHue:hue saturation:0.7 brightness:1.0 alpha:1.0];
CGContextSetStrokeColorWithColor(cacheContext, [color CGColor]);
CGContextSetLineCap(cacheContext, kCGLineCapRound);
CGContextSetLineWidth(cacheContext, 15);
CGPoint lastPoint = [touch previousLocationInView:self];
CGPoint newPoint = [touch locationInView:self];
CGContextMoveToPoint(cacheContext, lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(cacheContext, newPoint.x, newPoint.y);
CGContextStrokePath(cacheContext);
CGRect dirtyPoint1 = CGRectMake(lastPoint.x-10, lastPoint.y-10, 20, 20);
CGRect dirtyPoint2 = CGRectMake(newPoint.x-10, newPoint.y-10, 20, 20);
[self setNeedsDisplayInRect:CGRectUnion(dirtyPoint1, dirtyPoint2)];
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
CGContextRef context = UIGraphicsGetCurrentContext();
CGImageRef cacheImage = CGBitmapContextCreateImage(cacheContext);
CGContextDrawImage(context, self.bounds, cacheImage);
CGImageRelease(cacheImage);
}
In viewcontroller code:
PaintView *paint = [[PaintView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:paint];
[paint release];
in touches moved,,,
make a toggle for eraser and change the code as follows.
if(togleEraser == NO)
{
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 2.0);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0.0, 0.0, 0.0, 1.0);
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
}
else
{
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 20);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1, 0, 0, 10);
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextClearRect (UIGraphicsGetCurrentContext(), CGRectMake(lastPoint.x, lastPoint.y, 50, 50));
}

setNeedsDisplay: Too long between redraw cycles

I'm new to cocoa. I thought I could set the UITableViewCell background view to my own custom subclass in order to display a loading bar in the background of the cell, but it seems that calling setNeedsDisplay when I want to update the bar is not fast enough for my needs. Right now I'm updating it (by that I mean updating data in the UIView and then calling setNeedsDisplay) every .1 seconds and only seeing it actual update every 30-40 seconds. Is this normal? Is there any way to speed it up? If not are there other options for what I'm trying to do?
This is my code for draw rect (there's a helper methode above it) and updateBarAt, which is what is called to update it:
-(void) updateBarAt: (float) playHead {
self.playHead = playHead;
NSLog(#"%f", self.playHead);
[self setNeedsDisplay];
}
-(void) drawBackground: (CGRect) rect{
double totalTime = self.playFor + self.wait;
double waitPercentage = self.wait / totalTime;
double playForPercentage = (self.playFor - self.fadeIn - self.fadeOut) / totalTime;
double fadeInPercentage = self.fadeIn / totalTime;
double fadeOutPercentage = self.fadeOut / totalTime;
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect blueRect = CGRectMake((waitPercentage+fadeInPercentage)*rect.size.width, 0, playForPercentage*rect.size.width, rect.size.height);
CGContextSetRGBFillColor(context, .639, .737, 1, 1.0);
CGContextFillRect(context, blueRect);
CGRect greenRect = CGRectMake(0, 0, waitPercentage*rect.size.width, rect.size.height);
CGContextSetRGBFillColor(context, .843, 1, .651, 1.0);
CGContextFillRect(context, greenRect);
CGRect purpleRect = CGRectMake(waitPercentage*rect.size.width+.1, 0, fadeInPercentage*rect.size.width, rect.size.height);
CGContextSetRGBFillColor(context, .7451, .639, 1.0, 1.0);
CGContextFillRect(context, purpleRect);
CGRect purpleR = CGRectMake((1.0 - fadeOutPercentage)*rect.size.width - .5, 0, fadeOutPercentage*rect.size.width + .5, rect.size.height);
CGContextFillRect(context, purpleR);
}
- (void)drawRect:(CGRect)rect { //just does blue and green, need to add purple. Research
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0);
CGContextFillRect(context, rect);
if (self.playHead == -1)
return;
[super drawRect:rect];
double totalTime = self.playFor + self.wait;
double playedPercentage = self.playHead / totalTime;
double waitPercentage = self.wait / totalTime;
double playForPercentage = (self.playFor - self.fadeIn - self.fadeOut) / totalTime;
double fadeInPercentage = self.fadeIn / totalTime;
double fadeOutPercentage = self.fadeOut / totalTime;
NSLog(#"Played: %f Wait: %f Play: %f Fade In: %f Fade Out: %f", playedPercentage, waitPercentage, playForPercentage, fadeInPercentage, fadeOutPercentage);
if (playedPercentage <= waitPercentage) {
waitPercentage = playedPercentage;
playForPercentage = 0;
fadeInPercentage = 0;
fadeOutPercentage = 0;
} else if (playedPercentage <= waitPercentage+fadeInPercentage) {
playForPercentage = 0;
fadeInPercentage = playedPercentage - waitPercentage;
fadeOutPercentage = 0;
} else if (playedPercentage <= waitPercentage+fadeInPercentage + playForPercentage) {
playForPercentage = playedPercentage - waitPercentage - fadeInPercentage;
fadeOutPercentage = 0;
} else {
fadeOutPercentage = playedPercentage - waitPercentage - playForPercentage;
}
//[self drawBackground:rect];
CGRect blueRect = CGRectMake((waitPercentage+fadeInPercentage)*rect.size.width, 0, playForPercentage*rect.size.width, rect.size.height);
CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1.0);
CGContextFillRect(context, blueRect);
CGRect greenRect = CGRectMake(0, 0, waitPercentage*rect.size.width, rect.size.height);
CGContextSetRGBFillColor(context, 0.0, 1.0, 0.0, 1.0);
CGContextFillRect(context, greenRect);
CGRect purpleRect = CGRectMake(waitPercentage*rect.size.width+.1, 0, fadeInPercentage*rect.size.width, rect.size.height);
CGContextSetRGBFillColor(context, 0.33, 0.1, .55, 1.0);
CGContextFillRect(context, purpleRect);
CGRect purpleR = CGRectMake((1.0 - fadeOutPercentage)*rect.size.width - .5, 0, fadeOutPercentage*rect.size.width + .5, rect.size.height);
CGContextFillRect(context, purpleR);
}
Most UIKit use needs to be done on the main thread. Most likely your updateBarAt: method isn't being called on the main thread which means your call to setNeedsDisplay is being done on some background thread.
One possible solution would be this:
- (void)updateBarAt:(float)playHead {
self.playHead = playHead;
NSLog(#"%f", self.playHead);
dispatch_async(dispatch_get_main_queue(), ^{
[self setNeedsDisplay];
});
}
Another option would be to wrap the call to updateBarAt: in the dispatch_async call.

draw embossed arc using core graphics

I am trying to implement a custom slider as shown in figure below.
what I have done so far looks something like this
please help me out for drawing the arc with such effect. my code is as below, what I am doing is drawing the arc using CGContextAddArc with line width kLineWidth.
- (void)drawThumbAtPoint:(CGPoint)sliderButtonCenterPoint inContext: (CGContextRef)context {
UIGraphicsPushContext(context);
CGContextBeginPath(context);
CGContextMoveToPoint(context, sliderButtonCenterPoint.x, sliderButtonCenterPoint.y);
CGImageRef imageRef = [UIImage imageNamed:#"circle25.png"].CGImage;
CGRect rect = CGRectMake(sliderButtonCenterPoint.x - kThumbRadius, sliderButtonCenterPoint.y - kThumbRadius, kThumbRadius*2, kThumbRadius*2);
CGContextDrawImage(context, rect, imageRef);
//CGContextAddArc(context, sliderButtonCenterPoint.x, sliderButtonCenterPoint.y, kThumbRadius, 0.0, 2*M_PI, NO);
CGContextFillPath(context);
UIGraphicsPopContext();
}
- (CGPoint)drawArcTrack:(float)track atPoint:(CGPoint)center withRadius:(CGFloat)radius inContext:(CGContextRef)context {
UIGraphicsPushContext(context);
CGContextBeginPath(context);
float angleFromTrack = translateValueFromSourceIntervalToDestinationInterval(track, self.minimumValue, self.maximumValue, 0, M_PI/3);// 2*M_PI
CGFloat startAngle = (4*M_PI)/3;
CGFloat endAngle = startAngle + angleFromTrack;
CGContextAddArc(context, center.x, center.y, radius, startAngle, endAngle, NO);
CGPoint arcEndPoint = CGContextGetPathCurrentPoint(context);
CGContextStrokePath(context);
UIGraphicsPopContext();
return arcEndPoint;
}
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGPoint middlePoint;
middlePoint.x = self.bounds.origin.x + self.bounds.size.width/2;
middlePoint.y = self.bounds.origin.y + self.bounds.size.width;
CGContextSetLineWidth(context, kLineWidth);
CGFloat radius = [self sliderRadius];
[self.maximumTrackTintColor setStroke];
[self drawArcTrack:self.maximumValue atPoint:middlePoint withRadius:radius inContext:context];
[self.minimumTrackTintColor setStroke];
self.thumbCenterPoint = [self drawArcTrack:self.value atPoint:middlePoint withRadius:radius inContext:context];
[self.thumbTintColor setFill];
[self drawThumbAtPoint:self.thumbCenterPoint inContext:context];
}
Unless you are going to be changing the shape dynamically, you would probably be better off just creating the image in an image editor. I know it's easy to create that effect in Photoshop, Illustrator, or Fireworks.
That said, drawing an inner shadow like that with Core Graphics requires several steps:
Clip to the shape (using e.g. CGContextClip or CGContextClipToMask).
Make a path or mask of everything but the shape.
Set your shadow parameters (using CGContextSetShadowWithColor).
Fill the path or mask from step 2. This casts a shadow inside the shape, and only the shadow is drawn because you clipped to the shape in step 1.
If you do all of that correctly, you can get a nice result like this:
Here's the code I wrote to draw that. I wrote it in the drawRect: of a custom view subclass, but you can easily use this code to draw into any graphics context.
- (void)drawRect:(CGRect)rect {
CGContextRef gc = UIGraphicsGetCurrentContext();
First, I create a path that's just an arc:
static CGFloat const kArcThickness = 20.0f;
CGRect arcBounds = CGRectInset(self.bounds, 10.0f, 10.0f);
CGPoint arcCenter = CGPointMake(CGRectGetMidX(arcBounds), CGRectGetMidY(arcBounds));
CGFloat arcRadius = 0.5f * (MIN(arcBounds.size.width, arcBounds.size.height) - kArcThickness);
UIBezierPath *arc = [UIBezierPath bezierPathWithArcCenter:arcCenter radius:arcRadius startAngle:-M_PI / 3.0 endAngle:-2.0 * M_PI / 3.0 clockwise:NO];
Next, I ask Core Graphics to make a new path that is the outline of the arc path. Note how I ask it for a stroke width of kArcThickness and round line caps:
CGPathRef shape = CGPathCreateCopyByStrokingPath(arc.CGPath, NULL, kArcThickness, kCGLineCapRound, kCGLineJoinRound, 10.0f);
I also need the inverse of that path: a path that includes every point except the points in shape. It so happens (although I don't think it's documented) that CGContextCreateCopyByStrokingPath and CGPathAddRect draw in opposite directions. So if I copy shape and draw an enormous rectangle around it, the non-zero winding rule means that the new path will be the inverse of shape:
CGMutablePathRef shapeInverse = CGPathCreateMutableCopy(shape);
CGPathAddRect(shapeInverse, NULL, CGRectInfinite);
Now I can actually start drawing. First, I'll fill in the shape with a light gray color:
CGContextBeginPath(gc);
CGContextAddPath(gc, shape);
CGContextSetFillColorWithColor(gc, [UIColor colorWithWhite:.9 alpha:1].CGColor);
CGContextFillPath(gc);
Next I actually perform the four steps I listed above. I have to save the graphics state so I can undo the clipping and shadow parameters when I'm done.
CGContextSaveGState(gc); {
Step 1: clip to the shape:
CGContextBeginPath(gc);
CGContextAddPath(gc, shape);
CGContextClip(gc);
Step 2: Well, I did this step already when I created shapeInverse.
Step 3: I set the shadow parameters:
CGContextSetShadowWithColor(gc, CGSizeZero, 7, [UIColor colorWithWhite:0 alpha:.25].CGColor);
Step 4: I fill the inverse shape from step 2:
CGContextBeginPath(gc);
CGContextAddPath(gc, shapeInverse);
CGContextFillPath(gc);
Now I restore the graphics state, which specifically restores the clipping path and unsets the shadow parameters.
} CGContextRestoreGState(gc);
Finally, I'll stroke shape with a light gray to make the edge crisper:
CGContextSetStrokeColorWithColor(gc, [UIColor colorWithWhite:.75 alpha:1].CGColor);
CGContextSetLineWidth(gc, 1);
CGContextSetLineJoin(gc, kCGLineCapRound);
CGContextBeginPath(gc);
CGContextAddPath(gc, shape);
CGContextStrokePath(gc);
Of course I clean up when I'm done:
CGPathRelease(shape);
CGPathRelease(shapeInverse);
}
For more complex shapes, you can look at my answer here and my answer here.
Here's all the code together for easy copying:
- (void)drawRect:(CGRect)rect {
CGContextRef gc = UIGraphicsGetCurrentContext();
static CGFloat const kArcThickness = 20.0f;
CGRect arcBounds = CGRectInset(self.bounds, 10.0f, 10.0f);
CGPoint arcCenter = CGPointMake(CGRectGetMidX(arcBounds), CGRectGetMidY(arcBounds));
CGFloat arcRadius = 0.5f * (MIN(arcBounds.size.width, arcBounds.size.height) - kArcThickness);
UIBezierPath *arc = [UIBezierPath bezierPathWithArcCenter:arcCenter radius:arcRadius startAngle:-M_PI / 3.0 endAngle:-2.0 * M_PI / 3.0 clockwise:NO];
CGPathRef shape = CGPathCreateCopyByStrokingPath(arc.CGPath, NULL, kArcThickness, kCGLineCapRound, kCGLineJoinRound, 10.0f);
CGMutablePathRef shapeInverse = CGPathCreateMutableCopy(shape);
CGPathAddRect(shapeInverse, NULL, CGRectInfinite);
CGContextBeginPath(gc);
CGContextAddPath(gc, shape);
CGContextSetFillColorWithColor(gc, [UIColor colorWithWhite:.9 alpha:1].CGColor);
CGContextFillPath(gc);
CGContextSaveGState(gc); {
CGContextBeginPath(gc);
CGContextAddPath(gc, shape);
CGContextClip(gc);
CGContextSetShadowWithColor(gc, CGSizeZero, 7, [UIColor colorWithWhite:0 alpha:.25].CGColor);
CGContextBeginPath(gc);
CGContextAddPath(gc, shapeInverse);
CGContextFillPath(gc);
} CGContextRestoreGState(gc);
CGContextSetStrokeColorWithColor(gc, [UIColor colorWithWhite:.75 alpha:1].CGColor);
CGContextSetLineWidth(gc, 1);
CGContextSetLineJoin(gc, kCGLineCapRound);
CGContextBeginPath(gc);
CGContextAddPath(gc, shape);
CGContextStrokePath(gc);
CGPathRelease(shape);
CGPathRelease(shapeInverse);
}
check the below code for fully functional version of the above component, its working (may be its bit messy).
#import "UIArcSlider.h"
#interface UIArcSlider()
#property (nonatomic) CGPoint thumbCenterPoint;
#pragma mark - Init and Setup methods
- (void)setup;
#pragma mark - Thumb management methods
- (BOOL)isPointInThumb:(CGPoint)point;
#pragma mark - Drawing methods
- (CGFloat)sliderRadius;
- (void)drawThumbAtPoint:(CGPoint)sliderButtonCenterPoint inContext:(CGContextRef)context;
- (CGPoint)drawTheArcTrack:(float)track atPoint:(CGPoint)center withRadius:(CGFloat)radius AndColor:(Boolean) isWhite inContext:(CGContextRef)context;
- (CGPoint)drawTheLineTrack:(float)track withColor:(Boolean) isWhite inContext:(CGContextRef)context;
#end
#pragma mark -
#implementation UIArcSlider
#synthesize sliderStyle = _sliderStyle;
- (void)setSliderStyle:(UISliderStyle)sliderStyle {
if (sliderStyle != _sliderStyle) {
_sliderStyle = sliderStyle;
[self setNeedsDisplay];
}
}
#synthesize value = _value;
- (void)setValue:(float)value {
if (value != _value) {
if (value > self.maximumValue) { value = self.maximumValue; }
if (value < self.minimumValue) { value = self.minimumValue; }
_value = value;
[self setNeedsDisplay];
[self sendActionsForControlEvents:UIControlEventValueChanged];
}
}
#synthesize minimumValue = _minimumValue;
- (void)setMinimumValue:(float)minimumValue {
if (minimumValue != _minimumValue) {
_minimumValue = minimumValue;
if (self.maximumValue < self.minimumValue) { self.maximumValue = self.minimumValue; }
if (self.value < self.minimumValue) { self.value = self.minimumValue; }
}
}
#synthesize maximumValue = _maximumValue;
- (void)setMaximumValue:(float)maximumValue {
if (maximumValue != _maximumValue) {
_maximumValue = maximumValue;
if (self.minimumValue > self.maximumValue) { self.minimumValue = self.maximumValue; }
if (self.value > self.maximumValue) { self.value = self.maximumValue; }
}
}
#synthesize thumbCenterPoint = _thumbCenterPoint;
/** #name Init and Setup methods */
#pragma mark - Init and Setup methods
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self setup];
}
return self;
}
- (void)awakeFromNib {
[self setup];
}
- (void)setup {
self.value = 0.0;
self.minimumValue = 0.0;
self.maximumValue = 100.0;
self.thumbCenterPoint = CGPointZero;
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapGestureHappened:)];
[self addGestureRecognizer:tapGestureRecognizer];
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(panGestureHappened:)];
panGestureRecognizer.maximumNumberOfTouches = panGestureRecognizer.minimumNumberOfTouches;
[self addGestureRecognizer:panGestureRecognizer];
}
/** #name Drawing methods */
#pragma mark - Drawing methods
#define kLineWidth 22.0
#define kThumbRadius 20.0
#define kPadding 20.0
- (CGFloat)sliderRadius {
CGFloat radius = self.bounds.size.width;
radius -= MAX(kLineWidth + kPadding, kThumbRadius + kPadding);
return radius;
}
-(CGFloat)sliderWidth {
return self.bounds.size.width - kThumbRadius*2;
}
- (void)drawThumbAtPoint:(CGPoint)sliderButtonCenterPoint inContext:(CGContextRef)context {
UIGraphicsPushContext(context);
CGContextBeginPath(context);
CGContextMoveToPoint(context, sliderButtonCenterPoint.x, sliderButtonCenterPoint.y);
CGRect rect = CGRectMake(sliderButtonCenterPoint.x - kThumbRadius, sliderButtonCenterPoint.y - kThumbRadius, kThumbRadius*2, kThumbRadius*2);
CGImageRef imageRef = [UIImage imageNamed:#"circle25.png"].CGImage;
CGContextDrawImage(context, rect, imageRef);
UIGraphicsPopContext();
}
- (CGPoint)drawTheArcTrack:(float)track atPoint:(CGPoint)center withRadius:(CGFloat)radius AndColor:(Boolean) isWhite inContext:(CGContextRef)context
{
static CGFloat const kArcThickness = kLineWidth;
CGPoint arcCenter = center;
CGFloat arcRadius = radius;
float angleFromTrack = translateValueFromSourceIntervalToDestinationInterval(track, self.minimumValue, self.maximumValue, 0, M_PI/3);// 2*M_PI
CGFloat startAngle = (4*M_PI)/3;
CGFloat endAngle = startAngle + angleFromTrack;
UIBezierPath *arc = [UIBezierPath bezierPathWithArcCenter:arcCenter radius:arcRadius startAngle:startAngle endAngle:endAngle clockwise:YES];
CGPathRef shape = CGPathCreateCopyByStrokingPath(arc.CGPath, NULL, kArcThickness, kCGLineCapRound, kCGLineJoinRound, 10.0f);
CGMutablePathRef shapeInverse = CGPathCreateMutableCopy(shape);
CGPathAddRect(shapeInverse, NULL, CGRectInfinite);
CGPoint arcEndPoint = [arc currentPoint];
CGContextBeginPath(context);
CGContextAddPath(context, shape);
if (isWhite) {
CGContextSetFillColorWithColor(context, [UIColor colorWithWhite:.9 alpha:1].CGColor);
} else {//70,172, 220
CGContextSetFillColorWithColor(context, [UIColor colorWithRed:70/255.0 green:172/255.0 blue:220/255.0 alpha:1].CGColor);
}
CGContextFillPath(context);
CGContextSaveGState(context); {
CGContextBeginPath(context);
CGContextAddPath(context, shape);
CGContextClip(context);
if (isWhite) {
CGContextSetShadowWithColor(context, CGSizeZero, 7, [UIColor colorWithWhite:0 alpha:.25].CGColor);
} else {
CGContextSetShadowWithColor(context, CGSizeZero, 7, [UIColor colorWithRed:85/255.0 green:183/255.0 blue:230/255.0 alpha:.25].CGColor);
}
CGContextBeginPath(context);
CGContextAddPath(context, shapeInverse);
CGContextFillPath(context);
} CGContextRestoreGState(context);
if (isWhite) {
CGContextSetStrokeColorWithColor(context, [UIColor colorWithWhite:.75 alpha:1].CGColor);
} else {
CGContextSetStrokeColorWithColor(context, [UIColor colorWithRed:62/255.0 green:135/255.0 blue:169/255.0 alpha:1].CGColor);
}
CGContextSetLineWidth(context, 1);
CGContextSetLineJoin(context, kCGLineCapRound);
CGContextBeginPath(context);
CGContextAddPath(context, shape);
CGContextStrokePath(context);
CGPathRelease(shape);
CGPathRelease(shapeInverse);
return arcEndPoint;
}
- (CGPoint)drawTheLineTrack:(float)track withColor:(Boolean) isWhite inContext:(CGContextRef)context
{
CGFloat sliderWidth = [self sliderWidth];
CGFloat xStart = self.bounds.origin.x + (self.bounds.size.width - sliderWidth)/2;
CGFloat lineRectX = (self.bounds.size.width - sliderWidth)/2;
CGFloat lineThickness = kLineWidth/2;
CGFloat lineRectY = (self.bounds.size.height - lineThickness)/2;
CGFloat xPoint = translateValueToPoint(track, xStart, self.maximumValue, sliderWidth);
sliderWidth = xPoint;
CGRect lineRect = CGRectMake(lineRectX, lineRectY, sliderWidth, lineThickness);
UIBezierPath *line = [UIBezierPath bezierPathWithRoundedRect:lineRect cornerRadius:lineThickness/2];
CGPathRef shape = CGPathCreateCopyByStrokingPath(line.CGPath, NULL, lineThickness, kCGLineCapRound, kCGLineJoinRound, 10.0f);
CGMutablePathRef shapeInverse = CGPathCreateMutableCopy(shape);
CGPathAddRect(shapeInverse, NULL, CGRectInfinite);
CGPoint arcEndPoint = CGPointMake(lineRectX + xPoint, lineRectY + (lineThickness/2));
CGContextBeginPath(context);
CGContextAddPath(context, shape);
if (isWhite) {
CGContextSetFillColorWithColor(context, [UIColor colorWithWhite:.9 alpha:1].CGColor);
} else {//70,172, 220
CGContextSetFillColorWithColor(context, [UIColor colorWithRed:70/255.0 green:172/255.0 blue:220/255.0 alpha:1].CGColor);
}
CGContextFillPath(context);
CGContextSaveGState(context); {
CGContextBeginPath(context);
CGContextAddPath(context, shape);
CGContextClip(context);
if (isWhite) {
CGContextSetShadowWithColor(context, CGSizeZero, 7, [UIColor colorWithWhite:0 alpha:.25].CGColor);
} else {
CGContextSetShadowWithColor(context, CGSizeZero, 7, [UIColor colorWithRed:85/255.0 green:183/255.0 blue:230/255.0 alpha:.25].CGColor);
}
CGContextBeginPath(context);
CGContextAddPath(context, shapeInverse);
CGContextFillPath(context);
} CGContextRestoreGState(context);
if (isWhite) {
CGContextSetStrokeColorWithColor(context, [UIColor colorWithWhite:.75 alpha:1].CGColor);
} else {
CGContextSetStrokeColorWithColor(context, [UIColor colorWithRed:62/255.0 green:135/255.0 blue:169/255.0 alpha:1].CGColor);
}
CGRect outlineRect = CGRectMake(lineRectX - (lineThickness/2), lineRectY - (lineThickness/2), sliderWidth + lineThickness, lineThickness * 2);
UIBezierPath *outline = [UIBezierPath bezierPathWithRoundedRect:outlineRect cornerRadius:lineThickness];
CGContextSetLineWidth(context, 1);
CGContextSetLineJoin(context, kCGLineCapSquare);
CGContextBeginPath(context);
CGContextAddPath(context, outline.CGPath);
CGContextStrokePath(context);
CGPathRelease(shape);
CGPathRelease(shapeInverse);
return arcEndPoint;
}
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGPoint middlePoint;
switch (self.sliderStyle) {
case UISliderStyleLine:
[self drawTheLineTrack:self.maximumValue withColor:YES inContext:context];
self.thumbCenterPoint = [self drawTheLineTrack:self.value withColor:NO inContext:context];
[self drawThumbAtPoint:self.thumbCenterPoint inContext:context];
break;
case UISliderStyleArc:
default:
middlePoint.x = self.bounds.origin.x + self.bounds.size.width/2;
middlePoint.y = self.bounds.origin.y + self.bounds.size.width;
CGFloat radius = [self sliderRadius];
[self drawTheArcTrack:self.maximumValue atPoint:middlePoint withRadius:radius AndColor:YES inContext:context];
self.thumbCenterPoint = [self drawTheArcTrack:self.value atPoint:middlePoint withRadius:radius AndColor:NO inContext:context];
[self drawThumbAtPoint:self.thumbCenterPoint inContext:context];
break;
}
}
/** #name Thumb management methods */
#pragma mark - Thumb management methods
- (BOOL)isPointInThumb:(CGPoint)point {
CGRect thumbTouchRect = CGRectMake(self.thumbCenterPoint.x - kThumbRadius, self.thumbCenterPoint.y - kThumbRadius, kThumbRadius*2, kThumbRadius*2);
return CGRectContainsPoint(thumbTouchRect, point);
}
/** #name UIGestureRecognizer management methods */
#pragma mark - UIGestureRecognizer management methods
- (void)panGestureHappened:(UIPanGestureRecognizer *)panGestureRecognizer {
CGPoint tapLocation = [panGestureRecognizer locationInView:self];
switch (panGestureRecognizer.state) {
case UIGestureRecognizerStateChanged: {
CGFloat radius;
CGPoint sliderCenter;
CGPoint sliderStartPoint;
CGFloat angle;
CGFloat xStart;
CGFloat maximumValue;
CGFloat sliderWidth;
CGFloat point;
switch (self.sliderStyle) {
case UISliderStyleLine:
sliderWidth = [self sliderWidth];
xStart = self.bounds.origin.x + (self.bounds.size.width - sliderWidth)/2;
maximumValue = self.maximumValue;
point = tapLocation.x;
self.value = translatePointToValue(point, xStart, maximumValue, sliderWidth);
break;
case UISliderStyleArc:
default:
radius = [self sliderRadius];
sliderCenter = CGPointMake(self.bounds.size.width/2, self.bounds.size.width);
sliderStartPoint = CGPointMake(sliderCenter.x - (radius * 1.15), sliderCenter.y - (radius * 2.1) );
angle = angleBetweenThreePoints(sliderCenter, sliderStartPoint, tapLocation);
if (angle < 0) {
angle = -angle;
}
else {
angle = 0.0;
//angle = M_PI/3 - angle;
}
self.value = translateValueFromSourceIntervalToDestinationInterval(angle, 0, M_PI/3, self.minimumValue, self.maximumValue);
break;
}
}
default:
break;
}
}
- (void)tapGestureHappened:(UITapGestureRecognizer *)tapGestureRecognizer {
if (tapGestureRecognizer.state == UIGestureRecognizerStateEnded) {
CGPoint tapLocation = [tapGestureRecognizer locationInView:self];
if ([self isPointInThumb:tapLocation]) {
// do something on tap
}
else {
}
}
}
#end
/** #name Utility Functions */
#pragma mark - Utility Functions
float translateValueFromSourceIntervalToDestinationInterval(float sourceValue, float sourceIntervalMinimum, float sourceIntervalMaximum, float destinationIntervalMinimum, float destinationIntervalMaximum) {
float a, b, destinationValue;
a = (destinationIntervalMaximum - destinationIntervalMinimum) / (sourceIntervalMaximum - sourceIntervalMinimum);
b = destinationIntervalMaximum - a*sourceIntervalMaximum;
destinationValue = a*sourceValue + b;
return destinationValue;
}
float translateValueToPoint(float value, float xStart, float maximum, float width)
{
float point = (width * value) / maximum;
//
// point = xStart + point;
//
return point;
}
float translatePointToValue(float point, float xStart, float maximum, float width)
{
float value = (point) * maximum;
value = value / width;
return value;
}
CGFloat angleBetweenThreePoints(CGPoint centerPoint, CGPoint p1, CGPoint p2) {
CGPoint v1 = CGPointMake(p1.x - centerPoint.x, p1.y - centerPoint.y);
CGPoint v2 = CGPointMake(p2.x - centerPoint.x, p2.y - centerPoint.y);
CGFloat angle = atan2f(v2.x*v1.y - v1.x*v2.y, v1.x*v2.x + v1.y*v2.y);
return angle;
}
You'll require the thumb image as well

How to change color of the UIAlertView dialog in iOS?

I have an application where I am showing an alert message using UIAlertView. By default the color of the dialog box is blue. Can anyone tell me, how to change the color of that? Can it be changed?
Use Like This
[CustomAlert setBackgroundColor:[UIColor blueColor]
withStrokeColor:[UIColor greenColor]];
.h and .m File's Content
CustomAlert.h
#import <UIKit/UIKit.h>
#interface CustomAlert : UIAlertView
{
}
+ (void) setBackgroundColor:(UIColor *) background
withStrokeColor:(UIColor *) stroke;
#end
CustomAlert.m
#import "CustomAlert.h"
#interface CustomAlert (Private)
- (void) drawRoundedRect:(CGRect) rect inContext:(CGContextRef)
context withRadius:(CGFloat) radius;
#end
static UIColor *fillColor = nil;
static UIColor *borderColor = nil;
#implementation CustomAlert
+ (void) setBackgroundColor:(UIColor *) background
withStrokeColor:(UIColor *) stroke
{
if(fillColor != nil)
{
[fillColor release];
[borderColor release];
}
fillColor = [background retain];
borderColor = [stroke retain];
}
- (id)initWithFrame:(CGRect)frame
{
if((self = [super initWithFrame:frame]))
{
if(fillColor == nil)
{
fillColor = [[UIColor blackColor] retain];
borderColor = [[UIColor colorWithHue:0.625
saturation:0.0 brightness:0.8 alpha:0.8]
retain];
}
}
return self;
}
- (void)layoutSubviews
{
for (UIView *sub in [self subviews])
{
if([sub class] == [UIImageView class] && sub.tag == 0)
{
// The alert background UIImageView tag is 0,
// if you are adding your own UIImageView's
// make sure your tags != 0 or this fix
// will remove your UIImageView's as well!
[sub removeFromSuperview];
break;
}
}
}
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClearRect(context, rect);
CGContextSetAllowsAntialiasing(context, true);
CGContextSetLineWidth(context, 0.0);
CGContextSetAlpha(context, 0.8);
CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [borderColor CGColor]);
CGContextSetFillColorWithColor(context, [fillColor CGColor]);
// Draw background
CGFloat backOffset = 2;
CGRect backRect = CGRectMake(rect.origin.x + backOffset,
rect.origin.y + backOffset,
rect.size.width - backOffset*2,
rect.size.height - backOffset*2);
[self drawRoundedRect:backRect inContext:context withRadius:8];
CGContextDrawPath(context, kCGPathFillStroke);
// Clip Context
CGRect clipRect = CGRectMake(backRect.origin.x + backOffset-1,
backRect.origin.y + backOffset-1,
backRect.size.width - (backOffset-1)*2,
backRect.size.height - (backOffset-1)*2);
[self drawRoundedRect:clipRect inContext:context withRadius:8];
CGContextClip (context);
//Draw highlight
CGGradientRef glossGradient;
CGColorSpaceRef rgbColorspace;
size_t num_locations = 2;
CGFloat locations[2] = { 0.0, 1.0 };
CGFloat components[8] = { 1.0, 1.0, 1.0, 0.35, 1.0, 1.0, 1.0, 0.06 };
rgbColorspace = CGColorSpaceCreateDeviceRGB();
glossGradient = CGGradientCreateWithColorComponents(rgbColorspace,
components, locations, num_locations);
CGRect ovalRect = CGRectMake(-130, -115, (rect.size.width*2),
rect.size.width/2);
CGPoint start = CGPointMake(rect.origin.x, rect.origin.y);
CGPoint end = CGPointMake(rect.origin.x, rect.size.height/5);
CGContextSetAlpha(context, 1.0);
CGContextAddEllipseInRect(context, ovalRect);
CGContextClip (context);
CGContextDrawLinearGradient(context, glossGradient, start, end, 0);
CGGradientRelease(glossGradient);
CGColorSpaceRelease(rgbColorspace);
}
- (void) drawRoundedRect:(CGRect) rrect inContext:(CGContextRef) context
withRadius:(CGFloat) radius
{
CGContextBeginPath (context);
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);
}
- (void)dealloc
{
[super dealloc];
}
#end
From the UIAlertView Class Reference:
The UIAlertView class is intended to be used as-is and does not support subclassing. The view hierarchy for this class is private and must not be modified.
You have to implement your UIAlertView. You can't change the default blue color.
use a uiview to show alert instead of using UIAlertView then change the color of that view accordingly

Draw part of a circle

For an iPhone application I want to draw a circle, that is only for an x percentage filled.
Something like this:
I have no problems calculating the radius, the degrees or the radians, that is no problem. Also drawing the circle is already done. But how do I get the iPhone SDK to draw the part that is filled.
I can draw a rectangle that size, but not part of a circle.
I just want to draw that on a a normal context.
Hope someone can give me any pointers here.
A lot of people have showed you how this can be done in Core Graphics but it can also be done with Core Animation which gives the big addition of easily being able to animate the percentage of the pie shape.
The following code will create both the ring and the partly filled layers (even though you said that you already can draw the ring) since its nice to have both the ring and the pie shape to be drawn using the same method.
If you animate the strokeStart or strokeEnd properties of the pieShape layer you will have the percentage animate. As with all Core Animation code you will need to add QuartzCore.framework to your project and include <QuartzCore/QuartzCore.h> in your code.
// Create a white ring that fills the entire frame and is 2 points wide.
// Its frame is inset 1 point to fit for the 2 point stroke width
CGFloat radius = MIN(self.frame.size.width,self.frame.size.height)/2;
CGFloat inset = 1;
CAShapeLayer *ring = [CAShapeLayer layer];
ring.path = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(self.bounds, inset, inset)
cornerRadius:radius-inset].CGPath;
ring.fillColor = [UIColor clearColor].CGColor;
ring.strokeColor = [UIColor whiteColor].CGColor;
ring.lineWidth = 2;
// Create a white pie-chart-like shape inside the white ring (above).
// The outside of the shape should be inside the ring, therefore the
// frame needs to be inset radius/2 (for its outside to be on
// the outside of the ring) + 2 (to be 2 points in).
CAShapeLayer *pieShape = [CAShapeLayer layer];
inset = radius/2 + 2; // The inset is updated here
pieShape.path = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(self.bounds, inset, inset)
cornerRadius:radius-inset].CGPath;
pieShape.fillColor = [UIColor clearColor].CGColor;
pieShape.strokeColor = [UIColor whiteColor].CGColor;
pieShape.lineWidth = (radius-inset)*2;
// Add sublayers
// NOTE: the following code is used in a UIView subclass (thus self is a view)
// If you instead chose to use this code in a view controller you should instead
// use self.view.layer to access the view of your view controller.
[self.layer addSublayer:ring];
[self.layer addSublayer:pieShape];
Use CGContext's arc functions:
CGContextAddArc(context,
centerX,
centerY,
radius,
startAngleRadians,
endAngleRadians,
clockwise ? 1 : 0);
See the documentation for CGContextAddArc().
Try this:
CGContextMoveToPoint(the center point)
CGContextAddLineToPoint(the starting point of the fill path on the circumference)
CGContextAddArcToPoint(the ending point of the fill path on the circumference)
CGContextAddLineToPoint(the center point)
CGContextFillPath
I implemented a pie progress view that looks similar to what you are doing. It's open source. Hopefully the source code will help.
SSPieProgressView.h source
SSPieProgressView.m source
CircleViewController.h
#import <UIKit/UIKit.h>
#interface CircleViewController : UIViewController
#end
CircleViewController.m
#import "CircleViewController.h"
#import "GraphView.h"
#interface CircleViewController ()
#end
#implementation CircleViewController
- (void)viewDidLoad {
[super viewDidLoad];
GraphView *graphView = [[GraphView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
graphView.backgroundColor = [UIColor whiteColor];
graphView.layer.borderColor = [UIColor redColor].CGColor;
graphView.layer.borderWidth = 1.0f;
[self.view addSubview:graphView];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
GraphView.h
#import <UIKit/UIKit.h>
#interface GraphView : UIView
#end
GraphView.m
#import "GraphView.h"
#implementation GraphView
- (void)drawRect:(CGRect)rect {
CGPoint circleCenter = CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2);
[self drawCircleWithCircleCenter:(CGPoint) circleCenter radius:80 firstColor:[UIColor blueColor].CGColor secondeColor:[UIColor redColor].CGColor lineWidth:2 startDegree:0 currentDegree:90];
//[self drawCircleWithCircleCenter2:(CGPoint) circleCenter radius:80 firstColor:[UIColor blueColor].CGColor secondeColor:[UIColor redColor].CGColor lineWidth:2 startDegree:0 currentDegree:90];
}
- (void)drawCircleWithCircleCenter:(CGPoint) circleCenter
radius:(CGFloat)radius
firstColor:(CGColorRef)firstColor
secondeColor:(CGColorRef)secondeColor
lineWidth:(CGFloat)lineWidth
startDegree:(float)startDegree
currentDegree:(float)endDegree {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, lineWidth);
CGContextMoveToPoint(context, circleCenter.x, circleCenter.y);
CGContextAddArc(context, circleCenter.x , circleCenter.y, radius, [self radians:startDegree], [self radians:endDegree], 0);
CGContextSetFillColorWithColor(context, firstColor);
CGContextFillPath(context);
CGContextMoveToPoint(context, circleCenter.x, circleCenter.y);
CGContextAddArc(context, circleCenter.x, circleCenter.y, radius, [self radians:endDegree], [self radians:startDegree], 0);
CGContextSetFillColorWithColor(context, secondeColor);
CGContextFillPath(context);
}
- (void)drawCircleWithCircleCenter2:(CGPoint) circleCenter
radius:(CGFloat)radius
firstColor:(CGColorRef)firstColor
secondeColor:(CGColorRef)secondeColor
lineWidth:(CGFloat)lineWidth
startDegree:(float)startDegree
currentDegree:(float)endDegree {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, lineWidth);
CGContextMoveToPoint(context, circleCenter.x, circleCenter.y);
CGContextAddArc(context, circleCenter.x , circleCenter.y, radius, [self radians:startDegree], [self radians:endDegree], 0);
CGContextSetFillColorWithColor(context, firstColor);
CGContextFillPath(context);
CGContextMoveToPoint(context, circleCenter.x, circleCenter.y);
CGContextAddArc(context, circleCenter.x, circleCenter.y, radius, [self radians:endDegree], [self radians:startDegree], 0);
CGContextSetStrokeColorWithColor(context, secondeColor);
CGContextStrokePath(context);
}
-(float) radians:(double) degrees {
return degrees * M_PI / 180;
}
#end
note: you can use one of the 2 methods:
"drawCircleWithCircleCenter" or "drawCircleWithCircleCenter2"
this code if you want to split cell on 2 parts only
if you want to split cell on more than 2 parts you can check this : "Drawing a circle ,filled different parts with different color" and check the answer start with this Phrase "we have 6 class"
Well, since nobody used NSBezierPath so far, I figured I could provide the solution I recently used for the same problem:
-(void)drawRect:(NSRect)dirtyRect
{
double start = -10.0; //degrees
double end = 190.0; //degrees
NSPoint center = NSMakePoint(350, 200);
double radius = 50;
NSBezierPath *sector = [NSBezierPath bezierPath];
[sector moveToPoint:center];
[sector appendBezierPathWithArcWithCenter:center radius:radius startAngle:start endAngle:end];
[sector lineToPoint:center];
[sector fill];
}
Below is a full method I am using that does this with Core Graphics, adapting and expanding on mharper's comment above.
This code is for OSX Cocoa, but could easily be changed to iOS, by modifying how you get the context.
- (void)drawPieShapedCircleWithRadius:(CGFloat)radius
strokeColor:(CGColorRef)strokeColor
fillColor:(CGColorRef)fillColor
lineWidth:(CGFloat)lineWidth
currentDegrees:(float)currentDegrees
startDegrees:(float)startDegrees {
// get the context
CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
// Set the color of the circle stroke and fill
CGContextSetStrokeColorWithColor(context, strokeColor);
CGContextSetFillColorWithColor(context, fillColor);
// Set the line width of the circle
CGContextSetLineWidth(context, 1);
// Calculate the middle of the circle
CGPoint circleCenter = CGPointMake(self.frame.size.width / 2, self.frame.size.height / 2);
// Move the bezier to the center of the circle
CGContextMoveToPoint(context, circleCenter.x, circleCenter.y); // move to the center point
// Draw the arc from the start point (hardcoded as the bottom of the circle) to the center
CGContextAddLineToPoint(context, circleCenter.x, circleCenter.y + radius);
// Draw the arc around the circle from the start degrees point to the current degrees point
CGContextAddArc(context, circleCenter.x , circleCenter.y, radius, [self radians:startDegrees], [self radians:startDegrees + currentDegrees], 0);
// Draw the line back into the center of the circle
CGContextAddLineToPoint(context, circleCenter.x, circleCenter.y);
// Fill the circle
CGContextFillPath(context);
// Draw the line around the circle
CGContextStrokePath(context);
}
Try this code in a UIView, Example "MyChartClass"...
- (void)drawRect:(CGRect)rect {
int c=(int)[itemArray count];
CGFloat angleArray[c];
CGFloat offset;
int sum=0;
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetAllowsAntialiasing(context, false);
CGContextSetShouldAntialias(context, false);
for(int i=0;i<[itemArray count];i++) {
sum+=[[itemArray objectAtIndex:i] intValue];
}
for(int i=0;i<[itemArray count];i++) {
angleArray[i]=(float)(([[itemArray objectAtIndex:i] intValue])/(float)sum)*(2*3.14);
CGContextMoveToPoint(context, radius, radius);
if(i==0)
CGContextAddArc(context, radius, radius, radius, 0,angleArray[i], 0);
else
CGContextAddArc(context, radius, radius, radius,offset,offset+angleArray[i], 0);
offset+=angleArray[i];
CGContextSetFillColorWithColor(context, ((UIColor *)[myColorArray objectAtIndex:i]).CGColor);
CGContextClosePath(context);
CGContextFillPath(context);
}
}
Implementation in your UIViewController
MyChartClass *myChartClass=[[MyChartClass alloc]initWithFrame:CGRectMake(0, 0, 200, 200)];
myChartClass.backgroundColor = [UIColor clearColor];
myChartClass.itemArray=[[NSArray alloc]initWithObjects:#"75",#"25", nil];
myChartClass.myColorArray=[[NSArray alloc]initWithObjects:[UIColor blackColor],[UIColor whiteColor], nil];
myChartClass.radius=100;
[self.view addSubview:myChartClass];
Regards.