I am trying to create a circular progress indicator. Unfortunately, the drawRect routine is only called the first and last times from setNeedsDisplay which does not create the gradual fill pattern that I am looking for. I've created a UIView subclass where I populate a background and then update the draw progress as follows:
- (void)drawRect:(CGRect)rect
{
// draw background
CGFloat lineWidth = 5.f;
UIBezierPath *processBackgroundPath = [UIBezierPath bezierPath];
processBackgroundPath.lineWidth = lineWidth;
processBackgroundPath.lineCapStyle = kCGLineCapRound;
CGPoint center = CGPointMake(self.bounds.size.width / 2, self.bounds.size.width / 2);
CGFloat radius = (self.bounds.size.width - lineWidth) / 2;
CGFloat startAngle = (2 * (float)M_PI / 2); // 90 degrees
CGFloat endAngle = (2 * (float)M_PI) + startAngle;
[processBackgroundPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
[[UIColor grayColor] set];
[processBackgroundPath stroke];
// draw progress
UIBezierPath *processPath = [UIBezierPath bezierPath];
processPath.lineCapStyle = kCGLineCapRound;
processPath.lineWidth = lineWidth;
endAngle = (self.progress * 2 * (float)M_PI) + startAngle;
[processPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
[[UIColor blackColor] set];
[processPath stroke];
}
I set the progress variable with the following method:
- (void)setProgress:(float)progress {
_progress = progress;
[self setNeedsDisplay];
}
Then I simply call the attached method in my main viewcontroller after assigning a UIView with the above class to my storyboard:
- (void)progressView:(CircularProgress *)activityView loopTime:(CGFloat)duration repeats:(BOOL)repeat {
float portion = 0.0f;
while (portion < 1.0f) {
portion += 1/ (20.0 * duration);
[activityView setProgress:portion];
usleep(50000);
}
}
Again, the [self setNeedsDisplay] only calls drawRect the first and last time through. Thanks in advance for your help.