MonoTouch -- SetNeedsDisplay 不会刷新我的自定义 UIView
简单的概念:我有一个自定义 UIView,它绘制一条路径(一系列线条)。这些线条由用户通过触摸来定义。触摸后,我希望 Draw 方法重新绘制更新的路径/线条。代码:
这是我的自定义 UIView,名为“Renderer”:
public partial class Renderer : MonoTouch.UIKit.UIView
{
enum eClickMode
{
BeginPoint,
ControlPoint,
EndPoint
}
eClickMode _ClickMode = eClickMode.BeginPoint;
CGPath _Path = new CGPath();
PointF _ControlPoint, _EndPoint;
UIImage _ImageRough;
UIColor _Rough;
public Renderer (IntPtr ptr)
{
_ImageRough = new UIImage("/Users/general/Desktop/deeprough.jpg");
_Rough = UIColor.FromPatternImage(_ImageRough);
UIColor.Black.SetStroke();
// Set initial path to make sure something gets drawn
_Path = new CGPath();
_Path.MoveToPoint(100, 100);
_Path.AddQuadCurveToPoint(200, 200, 100, 300);
}
public override void Draw (RectangleF rect)
{
base.Draw (rect);
CGContext gfx = UIGraphics.GetCurrentContext();
_Rough.SetFill();
gfx.SetLineWidth(0);
gfx.AddPath(_Path);
gfx.DrawPath(CGPathDrawingMode.FillStroke);
}
public override void TouchesEnded (NSSet touches, UIEvent evt)
{
base.TouchesEnded (touches, evt);
UITouch touch = touches.ToArray<UITouch>()[0];
PointF pt = touch.LocationInView(this);
switch (_ClickMode)
{
case Renderer.eClickMode.BeginPoint:
_Path.MoveToPoint(pt);
_ClickMode = Renderer.eClickMode.ControlPoint;
break;
case eClickMode.ControlPoint:
_ControlPoint = pt;
_ClickMode = Renderer.eClickMode.EndPoint;
break;
case eClickMode.EndPoint:
_EndPoint = pt;
_Path.AddQuadCurveToPoint(_ControlPoint.X, _ControlPoint.Y, _EndPoint.X, _EndPoint.Y);
_Path.MoveToPoint(_EndPoint);
this.SetNeedsDisplay();
break;
}
}
}
这是我的 MainWindow.Designer 代码:
[MonoTouch.Foundation.Register("AppDelegate")]
public partial class AppDelegate {
private MonoTouch.UIKit.UIWindow __mt_window;
private Renderer __mt_renderer;
#pragma warning disable 0169
[MonoTouch.Foundation.Connect("window")]
private MonoTouch.UIKit.UIWindow window {
get {
this.__mt_window = ((MonoTouch.UIKit.UIWindow)(this.GetNativeField("window")));
return this.__mt_window;
}
set {
this.__mt_window = value;
this.SetNativeField("window", value);
}
}
[MonoTouch.Foundation.Connect("renderer")]
private Renderer renderer {
get {
this.__mt_renderer = ((Renderer)(this.GetNativeField("renderer")));
return this.__mt_renderer;
}
set {
this.__mt_renderer = value;
this.SetNativeField("renderer", value);
}
}
}
// Base type probably should be MonoTouch.UIKit.UIView or subclass
[MonoTouch.Foundation.Register("Renderer")]
public partial class Renderer {
}
我确信在 TouchesEnded 方法中, this.SetNeedsDisplay() 会受到攻击。但 Draw 方法仅在最初被调用。
我见过其他线程指出 Objective-C 中存在类似问题,但解决方案似乎始终与线程有关。好吧,我没有线程(至少我没有尝试)。这似乎是一个简单的概念(它在 .Net 中)。非常感谢任何帮助。
Simple concept: I have a custom UIView which draws a path (series of lines). These lines are defined by the user via touches. After a touch, I want the Draw method to redraw the updated path/lines. Code:
Here is my custom UIView called "Renderer":
public partial class Renderer : MonoTouch.UIKit.UIView
{
enum eClickMode
{
BeginPoint,
ControlPoint,
EndPoint
}
eClickMode _ClickMode = eClickMode.BeginPoint;
CGPath _Path = new CGPath();
PointF _ControlPoint, _EndPoint;
UIImage _ImageRough;
UIColor _Rough;
public Renderer (IntPtr ptr)
{
_ImageRough = new UIImage("/Users/general/Desktop/deeprough.jpg");
_Rough = UIColor.FromPatternImage(_ImageRough);
UIColor.Black.SetStroke();
// Set initial path to make sure something gets drawn
_Path = new CGPath();
_Path.MoveToPoint(100, 100);
_Path.AddQuadCurveToPoint(200, 200, 100, 300);
}
public override void Draw (RectangleF rect)
{
base.Draw (rect);
CGContext gfx = UIGraphics.GetCurrentContext();
_Rough.SetFill();
gfx.SetLineWidth(0);
gfx.AddPath(_Path);
gfx.DrawPath(CGPathDrawingMode.FillStroke);
}
public override void TouchesEnded (NSSet touches, UIEvent evt)
{
base.TouchesEnded (touches, evt);
UITouch touch = touches.ToArray<UITouch>()[0];
PointF pt = touch.LocationInView(this);
switch (_ClickMode)
{
case Renderer.eClickMode.BeginPoint:
_Path.MoveToPoint(pt);
_ClickMode = Renderer.eClickMode.ControlPoint;
break;
case eClickMode.ControlPoint:
_ControlPoint = pt;
_ClickMode = Renderer.eClickMode.EndPoint;
break;
case eClickMode.EndPoint:
_EndPoint = pt;
_Path.AddQuadCurveToPoint(_ControlPoint.X, _ControlPoint.Y, _EndPoint.X, _EndPoint.Y);
_Path.MoveToPoint(_EndPoint);
this.SetNeedsDisplay();
break;
}
}
}
Here is my MainWindow.Designer code:
[MonoTouch.Foundation.Register("AppDelegate")]
public partial class AppDelegate {
private MonoTouch.UIKit.UIWindow __mt_window;
private Renderer __mt_renderer;
#pragma warning disable 0169
[MonoTouch.Foundation.Connect("window")]
private MonoTouch.UIKit.UIWindow window {
get {
this.__mt_window = ((MonoTouch.UIKit.UIWindow)(this.GetNativeField("window")));
return this.__mt_window;
}
set {
this.__mt_window = value;
this.SetNativeField("window", value);
}
}
[MonoTouch.Foundation.Connect("renderer")]
private Renderer renderer {
get {
this.__mt_renderer = ((Renderer)(this.GetNativeField("renderer")));
return this.__mt_renderer;
}
set {
this.__mt_renderer = value;
this.SetNativeField("renderer", value);
}
}
}
// Base type probably should be MonoTouch.UIKit.UIView or subclass
[MonoTouch.Foundation.Register("Renderer")]
public partial class Renderer {
}
I know for sure that in the TouchesEnded method, this.SetNeedsDisplay() is getting hit. But the Draw method only gets called initially.
I've seen other threads indicating a similar problem in Objective-C, but the solution seems to always be about threading. Well, I'm not threading (at least I'm not trying to anyway). This seems like a simple concept (and it is in .Net). Any help is GREATLY appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您没有在 UIView 子类上调用正确的基本构造函数,您有:
您想要
You aren't calling the correct base constructor on your UIView subclass, you have:
You want