MonoTouch - SetNeedsDisplay不刷新我的自定义UIView

时间:2011-02-06 17:29:41

标签: uiview refresh xamarin.ios draw

简单概念:我有一个自定义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中)。非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

你没有在你的UIView子类上调用正确的基础构造函数,你有:

public Renderer (IntPtr ptr)

你想要

public Renderer (IntPtr ptr) : base (ptr)