Reputation: 743
I want to create a custom cell like one in the Mint app which does pretty much the same thing. How do I go about drawing the two bars using the earned and spent data?
Thanks,
I got this far:
-(void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
UIColor * earningStartColor = [UIColor colorWithRed:15/255.0f green:227/255.0f blue:0/255.0f alpha:1.0f];
UIColor * earningEndColor = [UIColor colorWithRed:15/255.0f green:188/255.0f blue:0/255.0f alpha:1.0f];
CGRect earningRect = CGRectMake(5, 32, 60, 13);
UIBezierPath *pathE = [UIBezierPath bezierPathWithRoundedRect:earningRect
cornerRadius:3.0];
[pathE addClip];
drawGlossAndGradient(context, earningRect, earningStartColor.CGColor, earningEndColor.CGColor);
UIColor * spentStartColor = [UIColor colorWithRed:255/255.0f green:88/255.0f blue:67/255.0f alpha:1.0f];
UIColor * spentEndColor = [UIColor colorWithRed:255/255.0f green:52/255.0f blue:49/255.0f alpha:1.0f];
CGRect spentRect = CGRectMake(5, 52, 25, 13);
UIBezierPath *pathS = [UIBezierPath bezierPathWithRoundedRect:spentRect
cornerRadius:5.0];
[pathS addClip];
drawGlossAndGradient(context, spentRect, spentStartColor.CGColor, spentEndColor.CGColor);
}
However, after addClip the drawing stops so only one bar is displayed. If i wrapped addClip around CGContextSaveGState & CGContextRestoreGState, only the second bar corners are rounded.
I also tried subclass a view and draw on the view then add as a subview to my tableviewcell and use cornerRadius, but the drawing is actually lying behind the view, so it appears as the rounded view (with its background) with the rectangle bar behind. I thought this should be easier than it is.
Upvotes: 0
Views: 1441
Reputation: 4731
Your bug is because of the [pathE addClip];
About the addClip
method , the apple doc said :
Important: If you need to remove the clipping region to perform subsequent drawing operations, you must save the current graphics state (using the CGContextSaveGState function) before calling this method. When you no longer need the clipping region, you can then restore the previous drawing properties and clipping region using the CGContextRestoreGState function.
so you should save the graphics state before addClip
and restore the graphics state after addClip
This can help you :
-(void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
UIColor * earningStartColor = [UIColor colorWithRed:15/255.0f green:227/255.0f blue:0/255.0f alpha:1.0f];
UIColor * earningEndColor = [UIColor colorWithRed:15/255.0f green:188/255.0f blue:0/255.0f alpha:1.0f];
CGRect earningRect = CGRectMake(5, 32, 60, 13);
UIBezierPath *pathE = [UIBezierPath bezierPathWithRoundedRect:earningRect
cornerRadius:3.0];
CGContextSaveGState(context);
[pathE addClip];
drawGlossAndGradient(context, earningRect, earningStartColor.CGColor, earningEndColor.CGColor);
CGContextRestoreGState(context);
UIColor * spentStartColor = [UIColor colorWithRed:255/255.0f green:88/255.0f blue:67/255.0f alpha:1.0f];
UIColor * spentEndColor = [UIColor colorWithRed:255/255.0f green:52/255.0f blue:49/255.0f alpha:1.0f];
CGRect spentRect = CGRectMake(5, 52, 25, 13);
UIBezierPath *pathS = [UIBezierPath bezierPathWithRoundedRect:spentRect
cornerRadius:5.0];
[pathS addClip];
drawGlossAndGradient(context, spentRect, spentStartColor.CGColor, spentEndColor.CGColor);
}
PS: I think you can post your drawGlossAndGradient
to the stackoverflow , so others can help easy , and may be helpful for others who search the answer.
And I fake the drawGlossAndGradient
method
void drawGlossAndGradient(CGContextRef context, CGRect rect, CGColorRef startColor,
CGColorRef endColor) {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat locations[] = {0.0, 1.0};
NSArray *colors = [NSArray arrayWithObjects:(__bridge id) startColor, (__bridge id) endColor, nil];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace,
(__bridge CFArrayRef) colors, locations);
CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
CGContextAddRect(context, rect);
CGContextClip(context);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGGradientRelease(gradient);
CGColorSpaceRelease(colorSpace);
}
The effect like this :
Upvotes: 3
Reputation: 5553
If you want to save yourself some coding, take a look at Core Plot, a Mac/iOS framework for drawing and animating graphs.
Upvotes: 1