Circular Progress Bar

Circular progress indicator We  all are familiar with native progress bar but a circular progress bar might be required in a project. In circular progress bar, progress of process will be shown by a bar filling in clockwise or anti-clockwise direction. Here I am providing the code to create a circular progress bar as shown in the image below: Circular Progress bar First create a class inheriting from NSView. Lets name it ProgressView. Now create a property named progress in  ProgressView, so that ProgressView.h class will look like :

#import <Cocoa/Cocoa.h> @interface ProgressView : NSView { float progress; } @property float progress; @end

Now implement the drawRect: method of  view to create a circular arc of length depending on the value of progress. Thus every time the view is redrawn, it will create a incomplete circle displaying the progress of a task. The code to draw a arc will be like :

CGContextRef myContext = [[NSGraphicsContext currentContext]graphicsPort];

CGPoint center = { self.bounds.size.width * 0.5f, self.bounds.size.height * 0.5f };

CGColorRef redColor = CGColorCreateGenericRGB(1, 0, 0, 1);

CGContextSetStrokeColorWithColor(myContext,redColor);

CGContextAddArc(myContext, center.x, center.y,

MIN(self.frame.size.width,self.frame.size.height)*0.4f, 0, progress, NO);

CGContextSetLineWidth(myContext, 5);

CGContextStrokePath(myContext);

CFRelease(redColor);

1) The center of the circle will be the center point of our view.

2) Set the color of the arc. I am setting it to red color.

3) void CGContextAddArc(CGContextRef c, CGFloat x, CGFloat y, CGFloat radius, CGFloat startAngle, CGFloat endAngle, int clockwise). In this method (x, y) is the center of the arc; ‘radius’ is its radius; ‘startAngle’ is the angle to the first endpoint of the arc; ‘endAngle’ is the angle to the second endpoint of the arc; and ‘clockwise’ is 1 if the arc is to be drawn clockwise, 0 otherwise. ‘startAngle’ and `endAngle’ are measured in radians. I am taking the start angle as 0 and end angle according to the value of progress.

4) Set the width of the line drawn. I am taking it 5 in this example. You may set its value as per your requirements. Hence, your ProgressView.m should now look like:

#import “ProgressView.h”

@implementation ProgressView

@synthesize progress;

– (id) initWithFrame:(NSRect)frame

{

self = [super initWithFrame:frame];

if (self)

{

// Initialization code here. self.progress = 0;

}

return self; }

// Show progress curve whenever view draws

– (void) drawRect:(NSRect)dirtyRect

{

if(progress)

{

CGContextRef myContext = [[NSGraphicsContext currentContext]graphicsPort];

CGPoint center = { self.bounds.size.width * 0.5f, self.bounds.size.height * 0.5f };

CGColorRef redColor = CGColorCreateGenericRGB(1, 0, 0, 1);

CGContextSetStrokeColorWithColor(myContext,redColor);

CGContextAddArc(myContext, center.x, center.y, MIN(self.frame.size.width,self.frame.size.height)*0.4f, 0, progress, NO);

CGContextSetLineWidth(myContext, 5); CGContextStrokePath(myContext);

CFRelease(redColor);

}

}

@end

Now, you may use this view as a progress indicator by just setting the value of its property “progress”. As an example below i am providing the code to increase the progress every second with NSTimer . For the same, you just need to draw the view with updated progress value, every time the timer method is called. Create a NSTimer object as below:

NSTimer* timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(progressClock) userInfo:nil repeats:YES];

Now in the selector method “progressClock” of NSTimer, set the updated progress value to the ProgressView’s object and then redraw the view.

– (void) progressClock

{

_progress = _progress + (2* M_PI / fullTime); [_view setProgress:_progress]; [_view setNeedsDisplay:YES];

}

where _view is  ProgressView object in the Xib, _progress is a class variable of float type initialised to 0 or initial progress value. And fullTime is the time in which you want to complete the progress/cicrle. Like if you want to fill the complete circle in 30 seconds, that means every second the progress should be increased by value (2*M_PI/30). So, here the fullTime will be 30. In this way you can easily create a circular progress indicator and modify it according to your requirements.

Written By: Neha Gupta, Software Engineer, Mindfire Solutions

Advertisements

About Neha Gupta

Software Engineer at Noida, India, Work on MAC OSX Application development with Cocoa, iOS development and Qt (Cross Platform Application Framework)

Posted on January 27, 2014, in Cocoa Application and tagged , , , , , , , , , , , . Bookmark the permalink. 3 Comments.

  1. Reblogged this on Developers Area.

  2. daviddelmonte

    Thanks @neha. Any chance of a macOS version in swift? I’m lazy.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: