Creating Different iOS Progress Types Using IGProgressView (Xcode & Xamarin.iOS)

Torrey Betts / Thursday, November 21, 2013

Introduction

The IGProgressView that comes with the NucliOS controls is an easy to use and extremely flexible control. It's unique design allows for many different progress visualizations, including custom shapes all in one control. This post will cover the many different visual possibilities of the IGProgressView to help you create stunning apps.

Standard

Standard

The #1 annotation shown shows the default shape of standard progress type with it's progress property set to 63.

// Objective-C
IGProgressView *standard1 = [[IGProgressView alloc] initWithStyle:IGProgressViewStyleStandard];
standard1.progress = 0.63;

// C#
IGProgressView standard1 = new IGProgressView (IGProgressViewStyle.IGProgressViewStyleStandard);
standard1.Progress = 0.63f;

The #2 annotation shown demonstrates setting the standardCornerRadius to 0 to achieve a square looking standard progress.

// Objective-C
IGProgressView *standard2 = [[IGProgressView alloc] initWithStyle:IGProgressViewStyleStandard];
standard2.progress = 0.63;
standard2.standardCornerRadius = 0;

// C#
IGProgressView standard2 = new IGProgressView (IGProgressViewStyle.IGProgressViewStyleStandard);
standard2.Progress = 0.63f;
standard2.StandardCornerRadius = 0;

The #3 annotation shown demonstrates the default standard progress shape with the lineWidth set to 5.0 on the exposed progressShapeLayer. This creates a bigger stroke around the displayed progress.

// Objective-C
IGProgressView *standard3 = [[IGProgressView alloc] initWithStyle:IGProgressViewStyleStandard];
standard3.progress = 0.63;
standard3.progressShapeLayer.lineWidth = 5.0;

// C#
IGProgressView standard3 = new IGProgressView (IGProgressViewStyle.IGProgressViewStyleStandard);
standard3.Progress = 0.63f;
standard3.ProgressShapeLayer.LineWidth = 5.0f;

Standard Indeterminate

Standard Indeterminate

The #1 annotation shown shows the default shape of standard indeterminate progress type.

// Objective-C
IGProgressView *standard1 = [[IGProgressView alloc] initWithStyle:IGProgressViewStyleStandardIndeterminate];

// C#
IGProgressView standard1 = new IGProgressView (IGProgressViewStyle.IGProgressViewStyleStandardIndeterminate);

The #2 annotation shown demonstrates setting the standardCornerRadius to 0 to achieve a square looking standard indeterminate progress.

// Objective-C
IGProgressView *standard2 = [[IGProgressView alloc] initWithStyle:IGProgressViewStyleStandardIndeterminate];
standard2.standardCornerRadius = 0;

// C#
IGProgressView standard2 = new IGProgressView (IGProgressViewStyle.IGProgressViewStyleStandardIndeterminate);
standard2.StandardCornerRadius = 0;

The #3 annotation shown demonstrates the default standard indeterminate progress shape with the lineWidth set to 5.0 on the exposed progressShapeLayer. This creates a bigger stroke around the displayed indeterminate progress.

// Objective-C
IGProgressView *standard3 = [[IGProgressView alloc] initWithStyle:IGProgressViewStyleStandardIndeterminate];
standard3.progressShapeLayer.lineWidth = 5.0;

// C#
IGProgressView standard3 = new IGProgressView (IGProgressViewStyle.IGProgressViewStyleStandardIndeterminate);
standard3.ProgressShapeLayer.LineWidth = 5.0f;

Diving Deeper into the Standard Progress Type

Diving Deeper into the Standard Progress Type

The IGProgressView exposes the CAShapeLayers that make up the progress (progressShapeLayer) and the progress track (progressTrackShapeLayer). This allows for complete control over the styling and the finer details of what's rendered. In the following snippet, the progress progressTintColor has been change to red, and by using the strokeColor property found on the exposed progressShapeLayer property, we change the stroke around the progress to be a deeper shape of red.

// Objective-C
IGProgressView *standard1 = [[IGProgressView alloc] initWithStyle:IGProgressViewStyleStandard];
standard1.progress = 0.63;
standard1.progressTintColor = [UIColor redColor];
standard1.standardCornerRadius = 5;
standard1.progressShapeLayer.lineWidth = 3.0;
standard1.progressShapeLayer.strokeColor = [UIColor colorWithRed:0.8 green:0 blue:0 alpha:1.0].CGColor;

// C#
IGProgressView standard1 = new IGProgressView (IGProgressViewStyle.IGProgressViewStyleStandard);
standard1.Progress = 0.63f;
standard1.ProgressTintColor = UIColor.Red;
standard1.StandardCornerRadius = 5;
standard1.ProgressShapeLayer.LineWidth = 3.0f;
standard1.ProgressShapeLayer.StrokeColor = UIColor.FromRGB(0.8f, 0.0f, 0.0f).CGColor;

Radial

Radial

The #1 annotation shown shows the default shape of radial progress type.

// Objective-C
IGProgressView *radial1 = [[IGProgressView alloc] initWithStyle:IGProgressViewStyleRadial];
radial1.progress = 0.63;

// C#
IGProgressView radial1 = new IGProgressView (IGProgressViewStyle.IGProgressViewStyleRadial);
radial1.Progress = 0.63f;

The #2 annotation shown demonstrates setting the radialInsertScale property to 0.5 to shrink the size of the inset down to expose more of the progress shape and track under it.

// Objective-C
IGProgressView *radial2 = [[IGProgressView alloc] initWithStyle:IGProgressViewStyleRadial];
radial2.progress = 0.63;
radial2.radialInsertScale = 0.5;

// C#
IGProgressView radial2 = new IGProgressView (IGProgressViewStyle.IGProgressViewStyleRadial);
radial2.Progress = 0.63f;
radial2.RadialInsertScale = 0.5f;

The #3 annotation shown demonstrates setting the radialInsertScale property to 0.0 to completely shrink the size of the inset down to nothing and expose the progress shape and track under it.

// Objective-C
IGProgressView *radial3 = [[IGProgressView alloc] initWithStyle:IGProgressViewStyleRadial];
radial3.progress = 0.63;
radial3.radialInsertScale = 0;

// C#
IGProgressView radial3 = new IGProgressView (IGProgressViewStyle.IGProgressViewStyleRadial);
radial3.Progress = 0.63f;
radial3.RadialInsertScale = 0.0f;

Radial Indeterminate

Radial Indeterminate

The #1 annotation shown shows the default shape of radial indeterminate progress type.

// Objective-C
IGProgressView *radial1 = [[IGProgressView alloc] initWithStyle:IGProgressViewStyleRadialIndeterminate];

// C#
IGProgressView radial1 = new IGProgressView (IGProgressViewStyle.IGProgressViewStyleRadialIndeterminate);

The #2 annotation shown demonstrates setting the radialInsertScale property to 0.5 to shrink the size of the inset down to expose more of the indeterminate progress shape and track under it.

// Objective-C
IGProgressView *radial2 = [[IGProgressView alloc] initWithStyle:IGProgressViewStyleRadialIndeterminate];
radial2.radialInsertScale = 0.5;

// C#
IGProgressView radial2 = new IGProgressView (IGProgressViewStyle.IGProgressViewStyleRadialIndeterminate);
radial2.RadialInsertScale = 0.5f;

The #3 annotation shown demonstrates setting the radialInsertScale property to 0.0 to completely shrink the size of the inset down to nothing and expose the indeterminate progress shape and track under it.

// Objective-C
IGProgressView *radial3 = [[IGProgressView alloc] initWithStyle:IGProgressViewStyleRadialIndeterminate];
radial3.radialInsertScale = 0;

// C#
IGProgressView radial3 = new IGProgressView (IGProgressViewStyle.IGProgressViewStyleRadialIndeterminate);
radial3.RadialInsertScale = 0.0f;

Diving Deeper into the Radial Progress Type

Diving Deeper into the Radial Progress Type

The IGProgressView exposes the CAShapeLayers that make up the progress (progressShapeLayer) and the progress track (progressTrackShapeLayer). This allows for complete control over the styling and the finer details of what's rendered. Additionally, the radial progress type has properties that allow you to set a radialStartAngle and radialEndAngle, as well as the radialInsertScale to control how much of the progress and track shape is exposed. In the following snippet, the radial progress is set with a radialStartAngle of 180 degrees and radialEndAngle of 0 degrees, and the radialInsertScale is set to 0.75.

// Objective-C
IGProgressView *radial1 = [[IGProgressView alloc] initWithStyle:IGProgressViewStyleRadial];
radial1.progress = 0.63;
radial1.radialInsertScale = 0.75;
radial1.radialStartAngle = 180;
radial1.radialEndAngle = 0;

// C#
IGProgressView radial1 = new IGProgressView (IGProgressViewStyle.IGProgressViewStyleRadialIndeterminate);
radial1.Progress = 0.63f;
radial1.RadialInsertScale = 0.75f;
radial1.RadialStartAngle = 180.0f;
radial1.RadialEndAngle = 0.0f;

Custom

Custom

The IGProgressView supports using a CGPath to create a custom progress shape. Mac apps such as PaintCode make the creation of these paths easy and the possiblities endless. In the code snippet below, we use a custom path that draws out 5 stars, each would represent 20% of the total progress. The progress property is then be set to 80%, which fills 4 out of the 5 stars.

// Objective-C
IGProgressView *custom1 = [[IGProgressView alloc] initWithCustomShape:[self starsPath].CGPath];
custom1.progress = 0.80;

- (UIBezierPath *)starsPath
{
    UIBezierPath *starsPath = [UIBezierPath bezierPath];
    [starsPath moveToPoint:CGPointMake(20.5, 6.5)];
    [starsPath addLineToPoint:CGPointMake(13.45, 16.79)];
    [starsPath addLineToPoint:CGPointMake(1.48, 20.32)];
    [starsPath addLineToPoint:CGPointMake(9.09, 30.21)];
    [starsPath addLineToPoint:CGPointMake(8.74, 42.68)];
    [starsPath addLineToPoint:CGPointMake(20.5, 38.5)];
    [starsPath addLineToPoint:CGPointMake(32.26, 42.68)];
    [starsPath addLineToPoint:CGPointMake(31.91, 30.21)];
    [starsPath addLineToPoint:CGPointMake(39.52, 20.32)];
    [starsPath addLineToPoint:CGPointMake(27.55, 16.79)];
    [starsPath addLineToPoint:CGPointMake(20.5, 6.5)];
    [starsPath closePath];
    [starsPath moveToPoint:CGPointMake(60.5, 6.5)];
    [starsPath addLineToPoint:CGPointMake(53.45, 16.79)];
    [starsPath addLineToPoint:CGPointMake(41.48, 20.32)];
    [starsPath addLineToPoint:CGPointMake(49.09, 30.21)];
    [starsPath addLineToPoint:CGPointMake(48.74, 42.68)];
    [starsPath addLineToPoint:CGPointMake(60.5, 38.5)];
    [starsPath addLineToPoint:CGPointMake(72.26, 42.68)];
    [starsPath addLineToPoint:CGPointMake(71.91, 30.21)];
    [starsPath addLineToPoint:CGPointMake(79.52, 20.32)];
    [starsPath addLineToPoint:CGPointMake(67.55, 16.79)];
    [starsPath addLineToPoint:CGPointMake(60.5, 6.5)];
    [starsPath closePath];
    [starsPath moveToPoint:CGPointMake(100.5, 6.5)];
    [starsPath addLineToPoint:CGPointMake(93.45, 16.79)];
    [starsPath addLineToPoint:CGPointMake(81.48, 20.32)];
    [starsPath addLineToPoint:CGPointMake(89.09, 30.21)];
    [starsPath addLineToPoint:CGPointMake(88.74, 42.68)];
    [starsPath addLineToPoint:CGPointMake(100.5, 38.5)];
    [starsPath addLineToPoint:CGPointMake(112.26, 42.68)];
    [starsPath addLineToPoint:CGPointMake(111.91, 30.21)];
    [starsPath addLineToPoint:CGPointMake(119.52, 20.32)];
    [starsPath addLineToPoint:CGPointMake(107.55, 16.79)];
    [starsPath addLineToPoint:CGPointMake(100.5, 6.5)];
    [starsPath closePath];
    [starsPath moveToPoint:CGPointMake(140.5, 6.5)];
    [starsPath addLineToPoint:CGPointMake(133.45, 16.79)];
    [starsPath addLineToPoint:CGPointMake(121.48, 20.32)];
    [starsPath addLineToPoint:CGPointMake(129.09, 30.21)];
    [starsPath addLineToPoint:CGPointMake(128.74, 42.68)];
    [starsPath addLineToPoint:CGPointMake(140.5, 38.5)];
    [starsPath addLineToPoint:CGPointMake(152.26, 42.68)];
    [starsPath addLineToPoint:CGPointMake(151.91, 30.21)];
    [starsPath addLineToPoint:CGPointMake(159.52, 20.32)];
    [starsPath addLineToPoint:CGPointMake(147.55, 16.79)];
    [starsPath addLineToPoint:CGPointMake(140.5, 6.5)];
    [starsPath closePath];
    [starsPath moveToPoint:CGPointMake(180.5, 6.5)];
    [starsPath addLineToPoint:CGPointMake(173.45, 16.79)];
    [starsPath addLineToPoint:CGPointMake(161.48, 20.32)];
    [starsPath addLineToPoint:CGPointMake(169.09, 30.21)];
    [starsPath addLineToPoint:CGPointMake(168.74, 42.68)];
    [starsPath addLineToPoint:CGPointMake(180.5, 38.5)];
    [starsPath addLineToPoint:CGPointMake(192.26, 42.68)];
    [starsPath addLineToPoint:CGPointMake(191.91, 30.21)];
    [starsPath addLineToPoint:CGPointMake(199.52, 20.32)];
    [starsPath addLineToPoint:CGPointMake(187.55, 16.79)];
    [starsPath addLineToPoint:CGPointMake(180.5, 6.5)];
    [starsPath closePath];
    return starsPath;
}

// C#
IGProgressView custom1 = new IGProgressView (starsPath().CGPath);
custom1.Progress = 0.80f;
 
public UIBezierPath starsPath()
{
    UIBezierPath starsPath = new UIBezierPath ();
    starsPath.MoveTo(new PointF(20.5f, 6.5f));
    starsPath.AddLineTo(new PointF(13.45f, 16.79f));
    starsPath.AddLineTo(new PointF(1.48f, 20.32f));
    starsPath.AddLineTo(new PointF(9.09f, 30.21f));
    starsPath.AddLineTo(new PointF(8.74f, 42.68f));
    starsPath.AddLineTo(new PointF(20.5f, 38.5f));
    starsPath.AddLineTo(new PointF(32.26f, 42.68f));
    starsPath.AddLineTo(new PointF(31.91f, 30.21f));
    starsPath.AddLineTo(new PointF(39.52f, 20.32f));
    starsPath.AddLineTo(new PointF(27.55f, 16.79f));
    starsPath.AddLineTo(new PointF(20.5f, 6.5f));
    starsPath.ClosePath();
    starsPath.MoveTo(new PointF(60.5f, 6.5f));
    starsPath.AddLineTo(new PointF(53.45f, 16.79f));
    starsPath.AddLineTo(new PointF(41.48f, 20.32f));
    starsPath.AddLineTo(new PointF(49.09f, 30.21f));
    starsPath.AddLineTo(new PointF(48.74f, 42.68f));
    starsPath.AddLineTo(new PointF(60.5f, 38.5f));
    starsPath.AddLineTo(new PointF(72.26f, 42.68f));
    starsPath.AddLineTo(new PointF(71.91f, 30.21f));
    starsPath.AddLineTo(new PointF(79.52f, 20.32f));
    starsPath.AddLineTo(new PointF(67.55f, 16.79f));
    starsPath.AddLineTo(new PointF(60.5f, 6.5f));
    starsPath.ClosePath();
    starsPath.MoveTo(new PointF(100.5f, 6.5f));
    starsPath.AddLineTo(new PointF(93.45f, 16.79f));
    starsPath.AddLineTo(new PointF(81.48f, 20.32f));
    starsPath.AddLineTo(new PointF(89.09f, 30.21f));
    starsPath.AddLineTo(new PointF(88.74f, 42.68f));
    starsPath.AddLineTo(new PointF(100.5f, 38.5f));
    starsPath.AddLineTo(new PointF(112.26f, 42.68f));
    starsPath.AddLineTo(new PointF(111.91f, 30.21f));
    starsPath.AddLineTo(new PointF(119.52f, 20.32f));
    starsPath.AddLineTo(new PointF(107.55f, 16.79f));
    starsPath.AddLineTo(new PointF(100.5f, 6.5f));
    starsPath.ClosePath();
    starsPath.MoveTo(new PointF(140.5f, 6.5f));
    starsPath.AddLineTo(new PointF(133.45f, 16.79f));
    starsPath.AddLineTo(new PointF(121.48f, 20.32f));
    starsPath.AddLineTo(new PointF(129.09f, 30.21f));
    starsPath.AddLineTo(new PointF(128.74f, 42.68f));
    starsPath.AddLineTo(new PointF(140.5f, 38.5f));
    starsPath.AddLineTo(new PointF(152.26f, 42.68f));
    starsPath.AddLineTo(new PointF(151.91f, 30.21f));
    starsPath.AddLineTo(new PointF(159.52f, 20.32f));
    starsPath.AddLineTo(new PointF(147.55f, 16.79f));
    starsPath.AddLineTo(new PointF(140.5f, 6.5f));
    starsPath.ClosePath();
    starsPath.MoveTo(new PointF(180.5f, 6.5f));
    starsPath.AddLineTo(new PointF(173.45f, 16.79f));
    starsPath.AddLineTo(new PointF(161.48f, 20.32f));
    starsPath.AddLineTo(new PointF(169.09f, 30.21f));
    starsPath.AddLineTo(new PointF(168.74f, 42.68f));
    starsPath.AddLineTo(new PointF(180.5f, 38.5f));
    starsPath.AddLineTo(new PointF(192.26f, 42.68f));
    starsPath.AddLineTo(new PointF(191.91f, 30.21f));
    starsPath.AddLineTo(new PointF(199.52f, 20.32f));
    starsPath.AddLineTo(new PointF(187.55f, 16.79f));
    starsPath.AddLineTo(new PointF(180.5f, 6.5f));
    starsPath.ClosePath();
}

Further Reference

Every styling point of the IGProgressView wasn't discussed in this post, but the IGProgress has a rich API that you'll find to be very easy to get up and running with. Below are links to the API reference page as well as the developer's guide.

API Reference for IGProgressView - http://help.infragistics.com/iOS/2013.2/gridapi/Classes/IGProgressView.html
Developer's Guide Documentation for IGProgressView - http://help.infragistics.com/iOS/2013.2/?page=IGProgressView.html

By Torrey Betts