0

Guys! I have a really good question I'm working with Paintcode 3 and im working in Xamarin.Forms(PCL/SAP) Project. I have a sample project running right now and i have a custom drawing in paintcode 3. However, I understand paintcode is suppose to work natively with c# Xamarin. However, I was thinking that i can create a custom renderer my xamarin.forms project then, extract a custom paintcode 3 drawing then, create a render and stick it there. My question before i post any code is has this approach been done before or anyone tried this?

Here is my code so far really simple stuff:

my Main Page:

   public class MainPageCS :ContentPage
{
    public MainPageCS()
    {

        // The root page of your application

        Title = "PCTest";
        Padding = new Thickness(0, 20, 0, 0);

        Content = new TestView
        {


            // draw object will go here once i render it.

            BackgroundColor = Color.Blue,
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.Center

        };

    }

}

Simple content page the Test view inherits from the Xamarin.forms view.

 public class TestView : View
{
    public TestView()
    {
    }
}

Now seems straightforward but, here's where it gets spooky Here is the paintcode project i created. here is the image. PaintCodeProjectImage

Now, here is the code that generated that image. TestChatBox.cs

namespace PaintCodeStyleKitTest
{
[Register("TestChatBox")]
public class TestChatBox : NSObject
{

    //// Cache

    private static UIImage imageOfChatIcon;
    private static NSObject[] chatIconTargets;

    //// Initialization

    static TestChatBox()
    {

        DrawChatIcon();
    }

    //// Drawing Methods

    public static void DrawChatIcon()
    {

        //// Oval 2 Drawing
        var oval2Path = new UIBezierPath();
        oval2Path.MoveTo(new CGPoint(105.65f, 43.5f));
        oval2Path.AddCurveToPoint(new CGPoint(55.59f, 56.97f), new CGPoint(87.51f, 43.64f), new CGPoint(69.43f, 48.13f));
        oval2Path.AddCurveToPoint(new CGPoint(35.44f, 96.92f), new CGPoint(38.57f, 67.85f), new CGPoint(31.85f, 82.81f));
        UIColor.Gray.SetStroke();
        oval2Path.LineWidth = 9.0f;
        oval2Path.LineCapStyle = CGLineCap.Round;
        oval2Path.Stroke();


        //// Bezier 2 Drawing
        var bezier2Path = new UIBezierPath();
        bezier2Path.MoveTo(new CGPoint(166.1f, 48.28f));
        bezier2Path.AddCurveToPoint(new CGPoint(166.1f, 131.72f), new CGPoint(199.3f, 71.32f), new CGPoint(199.3f, 108.68f));
        bezier2Path.AddCurveToPoint(new CGPoint(89.68f, 147.91f), new CGPoint(145.34f, 146.13f), new CGPoint(116.5f, 151.53f));
        bezier2Path.AddCurveToPoint(new CGPoint(43.5f, 169.5f), new CGPoint(71.56f, 159.66f), new CGPoint(43.5f, 169.5f));
        bezier2Path.AddCurveToPoint(new CGPoint(58.33f, 138.86f), new CGPoint(43.5f, 169.5f), new CGPoint(53.16f, 153.11f));
        bezier2Path.AddCurveToPoint(new CGPoint(45.9f, 131.72f), new CGPoint(53.95f, 136.8f), new CGPoint(49.78f, 134.42f));
        bezier2Path.AddCurveToPoint(new CGPoint(45.9f, 48.28f), new CGPoint(12.7f, 108.68f), new CGPoint(12.7f, 71.32f));
        bezier2Path.AddCurveToPoint(new CGPoint(166.1f, 48.28f), new CGPoint(79.09f, 25.24f), new CGPoint(132.91f, 25.24f));
        bezier2Path.ClosePath();
        UIColor.Red.SetStroke();
        bezier2Path.LineWidth = 9.0f;
        bezier2Path.Stroke();
    }

    //// Generated Images

    public static UIImage ImageOfChatIcon
    {
        get
        {
            if (imageOfChatIcon != null)
                return imageOfChatIcon;

            UIGraphics.BeginImageContextWithOptions(new CGSize(210.0f, 190.0f), false, 0);
            TestChatBox.DrawChatIcon();
            imageOfChatIcon = UIGraphics.GetImageFromCurrentImageContext();
            UIGraphics.EndImageContext();

            return imageOfChatIcon;
        }
    }

    //// Customization Infrastructure

    [Outlet]
    public NSObject[] ChatIconTargets
    {
        get { return chatIconTargets; }
        set
        {
            chatIconTargets = value;
            foreach (NSObject target in value)
            {
                target.PerformSelector(new ObjCRuntime.Selector("setImage:"), ImageOfChatIcon, 0);
            }
        }
    }

}

Now, above is what paintcode generated for me as i finished that simple image. From reading the paintcode documentation the generated code has to override the drawrect method in order to draw the picture see my Test.cs

 using System;   
    using Xamarin.Forms;
    using CoreGraphics;
    using UIKit;
    using System.Drawing;
    using Foundation;
    using PaintCodeStyleKitTest;
    namespace PCTest
    {
        public class Test : UIView
        {
            public Test()
            {
                TestChatBox.DrawChatIcon();
            }

            public override void Draw(CGRect rect)
            {

                base.Draw(rect);
                TestChatBox.DrawChatIcon();


            }


        }
    }

this overrides the draw method and supposedly draws the picture successfully, however, when I try to complete the custom render using my test renderer file.

    using System;
using Xamarin.Forms;
using PCTest;
using UIKit;
using Xamarin.Forms.Platform.iOS;
using PaintCodeStyleKitTest;
using PCTest.iOS;
using Foundation;
using UIKit;
using CoreGraphics;

[assembly: ExportRenderer(typeof(TestView), typeof(TestRenderer))]
namespace PCTest.iOS
{
    public class TestRenderer : ViewRenderer<TestView, Test>
    {
        Test txt;
        protected override void OnElementChanged(ElementChangedEventArgs <TestView> e )
            {
                base.OnElementChanged(e);
        if (Control == null)
        {
            //txt = new Test( tes);
            Test tests = new Test();

            SetNativeControl(new Test());

        }
            if (e.OldElement != null)
            {
                return;
            }

        }


 }


}

I run the my sample app and nothing gets drawn to the view. I wonder why. I tried to apply a simple content page just to see if my sample view would render however, it did not render can anyone point me in the right direction regarding this. is there anything i did anything wrong regarding my approach to this? Please Help!

Nijoel
  • 13
  • 8

1 Answers1

0

You are not assigning any dimensions to your custom control and thus the Frame of your custom UIView is never being set so it exists at 0,0 with a size of 0,0.

var test = new TestView
{
    WidthRequest = 200,
    HeightRequest = 200,
    BackgroundColor = Color.Blue,
    HorizontalOptions = LayoutOptions.Center,
    VerticalOptions = LayoutOptions.Center
};

enter image description here

SushiHangover
  • 73,120
  • 10
  • 106
  • 165
  • @SushiHangoverso was the other code I had in my other cs files correct? I understand that I was not initializing the frame correctly to render my picture. Would I have to make the suggestion you say in my Test.cs which subclass from UIView or my would have to make the change in my TestView which subclass the View? – Nijoel Feb 24 '17 at 20:34
  • @Nijoel It depends, your current `DrawChatIcon` is based upon hardcoded dimensions thus hard-coding the frame size with the `UIView` might make sense... I tend to use PaintCode's frame, constraint and variables to make parametric designs that resize to their container (i.e. a text entry field whose drawing might expand vertically by not horizontally as the font size of the entry field is changed...) It really depends upon the use-cases of how your vector art will be use in the UI and thus how much work you need to but into it... – SushiHangover Feb 24 '17 at 20:46
  • @Nijoel adding frame, constraint, variables within Paintcode can be a lot of work if you are never using it in the finished UI control... I have a lot of static drawings from Paintcode that I just drop into the Draw method of a control and I'm done. Other times I wire up the internal sizes of the control to the Paintcode drawing, other times I expose the Paintcode variables via control properties so they are can adjusted by the developer at design time or programmatically at runtime.... – SushiHangover Feb 24 '17 at 20:49
  • @Nijoel And yes, your other code worked fine...just the Frame was not ever set... – SushiHangover Feb 24 '17 at 20:50
  • using PaintCode's frame constraints and variables to make changes ideal? i would think overriding the drawrect then calling the method would be be okay may i have that sample code you sketched up so i can look into it further? Im using paintcode to intergrate their sketch model to application for a client since theres no such 3rd party tools that can do this for specifically xamarin forms pcl or sap and anything helps and im gladly you responded leading me in a good direction! – Nijoel Feb 24 '17 at 21:59
  • oh! I see thank you very much for the clarity sushi! I just now saw the other comments you posted! :D That makes a lot of sense. – Nijoel Feb 24 '17 at 22:03
  • I don't know if anyone has a similar issue but, i found a really good video which helped me piece everything together very well. -> https://www.youtube.com/watch?v=55r1wHdOLBo – Nijoel Feb 27 '17 at 07:08
  • Thank you @sushi your advice helped me very well! – Nijoel Feb 27 '17 at 07:09