在 Xamarin.iOS 中绘制圆圈 (Xamarin Monotouch) 以图形方式显示进度
Drawing Circles In Xamarin.iOS (Xamarin Monotouch) for Showing Progress Graphically
因为我是 Xamarin World 的新手,也是它的控件的新手。我想在我的单触摸应用程序中添加圆圈以显示工作进度。为了显示进度,我必须在圆圈中标记一条弧线。如果可能的话,任何人都可以帮助我提供示例代码。等待答复,在此先感谢您。
在 GLContext 上画一个圆并不难,与在 Objective-C 或 Swift.
中所做的一样
我假设您想创建自己的视图,您可以重复使用。为此,只需继承 UIView
:
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);
}
}
}
其实这才是我真正应该做的。它对我有用
这是它的样子。你可以像 class 文件一样创建它,你可以简单地分配给 UI 视图。
如需更多参考,您可以使用此示例项目 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)
将 _percentComplete 乘以 FULL_CIRCLE 得到两个圆弧(不同方向)的结束角度
计算半径
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);
圆图 75%
因为我是 Xamarin World 的新手,也是它的控件的新手。我想在我的单触摸应用程序中添加圆圈以显示工作进度。为了显示进度,我必须在圆圈中标记一条弧线。如果可能的话,任何人都可以帮助我提供示例代码。等待答复,在此先感谢您。
在 GLContext 上画一个圆并不难,与在 Objective-C 或 Swift.
中所做的一样我假设您想创建自己的视图,您可以重复使用。为此,只需继承 UIView
:
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);
}
}
}
其实这才是我真正应该做的。它对我有用
这是它的样子。你可以像 class 文件一样创建它,你可以简单地分配给 UI 视图。 如需更多参考,您可以使用此示例项目 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)
将 _percentComplete 乘以 FULL_CIRCLE 得到两个圆弧(不同方向)的结束角度
计算半径
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);
圆图 75%