Search code examples
c#ioscallbackxamarin.ioscore-graphics

Callback function end after creating instance of class (c#)


I wrote some code to draw something in a iOS App, if the server send some new coordinates to it.

I have a callback function that draw the coordinates. But when I create a new instance of a class in this function the callback exit without any error...

Does someone else have this problem before?

Here is my code if this is helping

    CGPath pathtotal;
    List<CGPath> path;

    CGPoint initialPoint;
    CGPoint latestPoint;

    DrawDrawerDraw drawDrawerDraw;

    public DrawGuessView(IntPtr handle) : base(handle)
    {
        BackgroundColor = UIColor.White;
        pathtotal = new CGPath();

        SocketEventHandler.Add("draw:drawer:draw", onDrawDrawerDraw);
    }

    public void onDrawDrawerDraw(dynamic obj)
    {
        drawDrawerDraw = (DrawDrawerDraw)obj;

        for (int i = 0; i <= drawDrawerDraw.coords.Count; i++)
        {
            if (initialPoint.X != (nfloat)drawDrawerDraw.coords[i].x0 && initialPoint.Y != (nfloat)drawDrawerDraw.coords[i].y0)
            {
                path[i] = new CGPath();
            }

            initialPoint.X = (nfloat)drawDrawerDraw.coords[i].x0;
            initialPoint.Y = (nfloat)drawDrawerDraw.coords[i].y0;

            latestPoint.X = (nfloat)drawDrawerDraw.coords[i].x1;
            latestPoint.Y = (nfloat)drawDrawerDraw.coords[i].y1;

            //add lines to the touch points
            if (path[i].IsEmpty)
            {
                path[i].AddLines(new CGPoint[] { initialPoint, latestPoint });
            }
            else
            {
                path[i].AddLineToPoint(latestPoint);
            }
        }

        SetNeedsDisplay();
    }

    public override void Draw(CGRect rect)
    {
        base.Draw(rect);

        try
        {
            foreach (var item in path)
            {
                if (!initialPoint.IsEmpty)
                {
                    //get graphics context
                    using (CGContext g = UIGraphics.GetCurrentContext())
                    {
                        //set up drawing attributes
                        g.SetLineWidth(2);
                        UIColor.Black.SetStroke();

                        //add geometry to graphics context and draw it
                        pathtotal.AddPath(item);

                        g.AddPath(pathtotal);
                        g.DrawPath(CGPathDrawingMode.Stroke);
                    }
                }
            }
        }
        catch (Exception e) { }
    }
}

Solution

  • There are two points you need to modify.

    1. Initialize path in DrawGuessView method

      public DrawGuessView(IntPtr handle) : base(handle)
      {
          BackgroundColor = UIColor.White;
          pathtotal = new CGPath();
          List<CGPath> path = new List<CGPath>();
          SocketEventHandler.Add("draw:drawer:draw", onDrawDrawerDraw);
      } 
      
    2. path[i] = new CGPath() will cause the ArgumentOutOfRangeException, we can't set value to the item in List by this way.

      Modify the loop

      CGPath pathItem = null;
      for (int i = 0; i <= drawDrawerDraw.coords.Count; i++)
      {
           if (initialPoint.X != (nfloat)drawDrawerDraw.coords[i].x0 && initialPoint.Y != (nfloat)drawDrawerDraw.coords[i].y0)
          {
               pathItem = new CGPath();
          }
      
          initialPoint.X = (nfloat)drawDrawerDraw.coords[i].x0;
          initialPoint.Y = (nfloat)drawDrawerDraw.coords[i].y0;
      
          latestPoint.X = (nfloat)drawDrawerDraw.coords[i].x1;
          latestPoint.Y = (nfloat)drawDrawerDraw.coords[i].y1;
      
          //add lines to the touch points
          if (pathItem.IsEmpty)
          {
              pathItem.AddLines(new CGPoint[] { initialPoint, latestPoint });
          }
          else
          {
              pathItem.AddLineToPoint(latestPoint);
          }
          path.Add(pathItem);
      }