As I'm very new to Xamarin World and new to its controls. I would like to add Circles to Show Work Progress in my mono touch app. For showing Progress I have to mark an Arc in the circle. And if possible any one can help with me a sample code. Awaiting an answer, Thanks a lot in advance.
using System;
using UIKit;
using CoreGraphics;
namespace CircleTest.Touch
{
public class CircleGraph : UIView
{
int _radius = 10;
int _lineWidth = 10;
nfloat _degrees = 0.0f;
UIColor _backColor = UIColor.FromRGB(46, 60, 76);
UIColor _frontColor = UIColor.FromRGB(234, 105, 92);
//FromRGB (234, 105, 92);
public CircleGraph (CGRect frame, int lineWidth, nfloat degrees)
{
_lineWidth = lineWidth;
_degrees = degrees;
this.Frame = new CGRect(frame.X, frame.Y, frame.Width, frame.Height);
this.BackgroundColor = UIColor.Clear;
}
public CircleGraph (CGRect frame, int lineWidth, UIColor backColor, UIColor frontColor)
{
_lineWidth = lineWidth;
this.Frame = new CGRect(frame.X, frame.Y, frame.Width, frame.Height);
this.BackgroundColor = UIColor.Clear;
}
public override void Draw (CoreGraphics.CGRect rect)
{
base.Draw (rect);
using (CGContext g = UIGraphics.GetCurrentContext ()) {
_radius = (int)( (this.Bounds.Width) / 3) - 8;
DrawGraph(g, this.Bounds.GetMidX(), this.Bounds.GetMidY());
};
}
public void DrawGraph(CGContext g,nfloat x0,nfloat y0) {
g.SetLineWidth (_lineWidth);
// Draw background circle
CGPath path = new CGPath ();
_backColor.SetStroke ();
path.AddArc (x0, y0, _radius, 0, 2.0f * (float)Math.PI, true);
g.AddPath (path);
g.DrawPath (CGPathDrawingMode.Stroke);
// Draw overlay circle
var pathStatus = new CGPath ();
_frontColor.SetStroke ();
pathStatus.AddArc(x0, y0, _radius, 0, _degrees * (float)Math.PI, false);
g.AddPath (pathStatus);
g.DrawPath (CGPathDrawingMode.Stroke);
}
}
}
Actually this is what iam actually supposed to do. Its working for me
This is how it look like. U can create it like a class file and simply u can assign to a UIView. For more reference you can use this sample project Pi Graph
[EDIT]: The Draw
method originally passed the View.Frame
x,y to the DrawGraph
method. This should be View.Bounds
(modified above to reflect this). Remember that the frame x,y is in reference to the containing superview and bounds is referenced to the current view. This would have worked if the view was added at 0,0 but once you start moving around the UI it disappears. When the arcs are drawn the values for x,y passed to AddArc need to be in reference to the current view not the parent superview.
Drawing a circle on a GLContext isn't that hard to do and is the same as you would do in Objective-C or Swift.
I assume you want to create your own view which you can reuse. To do so, simply inherit from UIView
:
public class CircleView : UIView
{
}
Now to draw anything in your new custom view you want to override the Draw
method:
public override void Draw(RectangleF rect)
{
base.Draw(rect);
// draw stuff in here
}
To draw stuff you need to get hold of the current context from UIGraphics
, which can be done like so:
using (var gctx = UIGraphics.GetCurrentContext())
{
// use gctx to draw stuff
}
The CGContext
you get back, is very similar to Canvas
on Android for instance. It has helper methods to draw arcs, circles, rectangles, points and much more.
So to draw a simple circle in that context, you do:
gctx.SetFillColor(UIColor.Cyan.CGColor);
gctx.AddEllipseInRect(rect);
So combine everything you get:
public class CircleView : UIView
{
public override Draw(RectangleF rect)
{
base.Draw(rect);
using (var gctx = UIGraphics.GetCurrentContext())
{
gctx.SetFillColor(UIColor.Cyan.CGColor);
gctx.AddEllipseInRect(rect);
}
}
}
That is it! Well, not exactly, this is where you need to start think of how you want to draw your progress indicator. What I think would probably work is:
gctx.AddArc()
, which can take an angle and draw an arc.To draw a string you will need to convert your string to a NSAttributedString
then use CTLine
to draw the text like:
using(var line = new CTLine(nsAttrString))
line.Draw(gctx);
Minor alterations to the answer provided by @SARATH as copying and pasting did not yield the desired result.
Changed _degrees to _percentComplete
Fixed overload constructor for changing colors by adding a param for percentComplete and added missing member variable assignments for _backColor and _frontColor
Added constant float value for drawing a full circle (FULL_CIRCLE)
Multiply _percentComplete by FULL_CIRCLE to get the end angle for both arcs (with different directions)
Calculation of the radius
public class CircleGraph : UIView
{
const float FULL_CIRCLE = 2 * (float)Math.PI;
int _radius = 10;
int _lineWidth = 10;
nfloat _percentComplete = 0.0f;
UIColor _backColor = UIColor.LightGray; //UIColor.FromRGB(46, 60, 76);
UIColor _frontColor = UIColor.Green; //UIColor.FromRGB(234, 105, 92);
public CircleGraph(CGRect frame, int lineWidth, nfloat percentComplete)
{
_lineWidth = lineWidth;
_percentComplete = percentComplete;
this.Frame = new CGRect(frame.X, frame.Y, frame.Width, frame.Height);
this.BackgroundColor = UIColor.Clear;
}
public CircleGraph(CGRect frame, int lineWidth, nfloat percentComplete, UIColor backColor, UIColor frontColor)
{
_lineWidth = lineWidth;
_percentComplete = percentComplete;
this.Frame = new CGRect(frame.X, frame.Y, frame.Width, frame.Height);
this.BackgroundColor = UIColor.Clear;
_backColor = backColor;
_frontColor = frontColor;
}
public override void Draw(CoreGraphics.CGRect rect)
{
base.Draw(rect);
using (CGContext g = UIGraphics.GetCurrentContext())
{
var diameter = Math.Min(this.Bounds.Width, this.Bounds.Height);
_radius = (int)(diameter / 2) - _lineWidth;
DrawGraph(g, this.Bounds.GetMidX(), this.Bounds.GetMidY());
};
}
public void DrawGraph(CGContext g, nfloat x, nfloat y)
{
g.SetLineWidth(_lineWidth);
// Draw background circle
CGPath path = new CGPath();
_backColor.SetStroke();
path.AddArc(x, y, _radius, 0, _percentComplete * FULL_CIRCLE, true);
g.AddPath(path);
g.DrawPath(CGPathDrawingMode.Stroke);
// Draw overlay circle
var pathStatus = new CGPath();
_frontColor.SetStroke();
// Same Arc params except direction so colors don't overlap
pathStatus.AddArc(x, y, _radius, 0, _percentComplete * FULL_CIRCLE, false);
g.AddPath(pathStatus);
g.DrawPath(CGPathDrawingMode.Stroke);
}
}
Example
var circleGraph = new CircleGraph(circleGraphView.Frame, 20, 0.75f);
CircleGraph at 75%
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With