在Xamarin.iOS(Xamarin Monotouch)中绘制圆圈以图形方式显示进度
因为我对Xamarin World非常陌生并且对其控件不熟悉 。 我想在我的单声道触摸应用程序中添加Circles to Show Work Progress。 为了显示进度,我必须在圆圈中标记一个圆弧。 如果可能的话,任何人都可以帮我一个示例代码。 等待回答,非常感谢提前。
在GLContext上绘制一个圆圈并不难,并且与在Objective-C或Swift中的操作相同。
我假设你想创建自己的视图,你可以重用它。 为此,只需从UIView
inheritance:
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); } } }
这就对了! 嗯,不完全是,这是您需要开始考虑如何绘制进度指示器的地方。 我认为可能有用的是:
- 画背景
- 画边框
- 以百分比计算进度的度数
- 使用度数使用
gctx.AddArc()
创建弧,它可以采用角度并绘制弧。 - 在中间绘制百分比作为字符串
要绘制字符串,您需要将字符串转换为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%