在Xamarin.iOS(Xamarin Monotouch)中绘制圆圈以图形方式显示进度

因为我对Xamarin World非常陌生并且对其控件不熟悉 。 我想在我的单声道触摸应用程序中添加Circles to Show Work Progress。 为了显示进度,我必须在圆圈中标记一个圆弧。 如果可能的话,任何人都可以帮我一个示例代码。 等待回答,非常感谢提前。 我喜欢用两个文本字段init添加这样的图像

在GLContext上绘制一个圆圈并不难,并且与在Objective-C或Swift中的操作相同。

我假设你想创建自己的视图,你可以重用它。 为此,只需从UIViewinheritance:

 public class CircleView : UIView { } 

现在要在新的自定义视图中绘制任何内容,您要覆盖Draw方法:

 public override void Draw(RectangleF rect) { base.Draw(rect); // draw stuff in here } 

要绘制东西,你需要掌握UIGraphics的当前上下文,这可以这样做:

 using (var gctx = UIGraphics.GetCurrentContext()) { // use gctx to draw stuff } 

你得到的CGContext与Android上的Canvas非常相似。 它有辅助方法来绘制圆弧,圆,矩形,点等等。

因此,要在该上下文中绘制一个简单的圆,您可以:

 gctx.SetFillColor(UIColor.Cyan.CGColor); gctx.AddEllipseInRect(rect); 

所以结合你得到的一切:

 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); } } } 

这就对了! 嗯,不完全是,这是您需要开始考虑如何绘制进度指示器的地方。 我认为可能有用的是:

  1. 画背景
  2. 画边框
  3. 以百分比计算进度的度数
  4. 使用度数使用gctx.AddArc()创建弧,它可以采用角度并绘制弧。
  5. 在中间绘制百分比作为字符串

要绘制字符串,您需要将字符串转换为NSAttributedString然后使用CTLine绘制文本,如:

 using(var line = new CTLine(nsAttrString)) line.Draw(gctx); 

视图的结果

 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); } } } 

实际上这就是我实际应该做的事情。 它为我工作

这就是它的样子。 你可以像类文件一样创建它,你可以简单地分配给UIView。 有关更多参考,您可以使用此示例项目Pi Graph

[编辑]: Draw方法最初将View.Frame x,y传递给DrawGraph方法。 这应该是View.Bounds (上面修改以反映这一点)。 请记住,框架x,y是对包含的超级视图的引用,并且边界是引用当前视图的。 如果视图是在0,0处添加的话,这将有效,但是一旦你开始在UI中移动它就会消失。 绘制弧时,传递给AddArc的x,y的值需要引用当前视图而不是父超级视图。

@SARATH作为复制和粘贴提供的答案的微小改动没有产生预期的结果。

将_degrees更改为_percentComplete

修复了通过为percentComplete添加参数来更改颜色的重载构造函数,并为_backColor和_frontColor添加了缺少的成员变量赋值

添加常量浮点值以绘制整圆(FULL_CIRCLE)

用FULL_CIRCLE乘以_percentComplete来获得两个弧的结束角度(具有不同的方向)

计算半径

  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); } } 

 var circleGraph = new CircleGraph(circleGraphView.Frame, 20, 0.75f); 

CircleGraph占75%

CircleGraph显示75%

Interesting Posts