2011-02-06 3 views
1

Concept simple: J'ai un UIView personnalisé qui trace un chemin (série de lignes). Ces lignes sont définies par l'utilisateur via des touches. Après un contact, je souhaite que la méthode Draw redessine le chemin/les lignes mis à jour. Code:MonoTouch - SetNeedsDisplay n'actualise pas mon UIView personnalisé

Voici mon UIView personnalisé appelé "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; 
     } 
    } 
} 

Voici mon code 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 { 
} 

Je sais avec certitude que dans la méthode touchesEnded, cela. SetNeedsDisplay() est en train d'être touché. Mais la méthode Draw est appelée uniquement initialement.

J'ai vu d'autres threads indiquant un problème similaire dans Objective-C, mais la solution semble toujours concerner le threading. Eh bien, je ne filage pas (du moins je n'essaie pas de toute façon). Cela semble être un concept simple (et c'est dans .Net). Toute aide est grandement appréciée.

+0

Cela devrait fonctionner, peut-être il y a un bug quelque part ailleurs dans votre application . N'hésitez pas à poster un cas de test autonome complet. –

Répondre

1

Vous n'êtes pas appeler le constructeur de base correcte sur votre sous-classe UIView, vous avez:

public Renderer (IntPtr ptr) 

Vous voulez

public Renderer (IntPtr ptr) : base (ptr) 
Questions connexes