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). Любая помощь ОЧЕНЬ приветствуется.


person user605468    schedule 06.02.2011    source источник
comment
Это должно сработать, возможно, в вашем приложении есть ошибка. Не стесняйтесь опубликовать полный автономный тестовый пример.   -  person miguel.de.icaza    schedule 07.02.2011


Ответы (1)


Вы не вызываете правильный базовый конструктор в своем подклассе UIView, у вас есть:

public Renderer (IntPtr ptr)

Вы хотите

public Renderer (IntPtr ptr) : base (ptr)
person Geoff Norton    schedule 08.02.2011