Friday, June 19, 2009

UIProgressView custom draw method

Code snippet of a UIProgressView subclass that implements custom draw method.
This example uses four images for the left side, right side and ten sections that can be either on/off or partially filled.
My images included edge and shadow and named: pb_left.png (9x32), pb_right.png (9x32), pb_on.png (28x32). pb_off.png (28x32)

- (void)awakeFromNib
[self setBackgroundColor:[UIColor clearColor]];

// allow non-clear background color in Interface Builder, but do not draw it
- (BOOL)getClearsContextBeforeDrawing
return NO;

// draw left and right edge of progress bar with filled sections between
- (void)drawRect:(CGRect)rect
const int numParts = 10;
UIImage *pb_left = [UIImage imageNamed:@"pb_left.png"]; // "["
UIImage *pb_right = [UIImage imageNamed:@"pb_right.png"]; // "]"
UIImage *pb_on = [UIImage imageNamed:@"pb_on.png"]; // "X"
UIImage *pb_off = [UIImage imageNamed:@"pb_off.png"]; // " "
CGPoint p = {0,0};
[pb_left drawAtPoint:p];
p.x = pb_left.size.width;
int q = (int)(self.progress * numParts);
for (int i=0; i<numParts; i++)
if (i == q) // partial on/off section. works with semi-transparent images too
float w = truncf(pb_on.size.width * fmodf(self.progress * numParts, 1.0f));
[pb_on drawInRect:CGRectMake(p.x, p.y, w, pb_on.size.height)];
[pb_off drawInRect:CGRectMake(p.x + w, p.y, pb_on.size.width - w, pb_on.size.height)];
else if (i < q)
[pb_on drawAtPoint:p];
else // (i > q)
[pb_off drawAtPoint:p];
p.x += pb_on.size.width;
[pb_right drawAtPoint:p];


Jason Fried said...

Can you share the full code. Been trying to figure out how to do this all day but not that advanced yet.


Juan Cruz said...

Its a grate post! but i can't make it work :(.
Have you got an example?