xamarin / SignaturePad

MIT License
245 stars 150 forks source link

Loading strokes doesn't work on Xamarin.Forms #170

Open SuNNjek opened 5 years ago

SuNNjek commented 5 years ago

Description

I'm trying to restore a signature that I created earlier. The points are stored in a database along with a TouchUp field from which I can restore the strokes. The problem is that the setter for the Strokes property seems to ignore the value I put in and so the signature doesn't load.

Expected Behavior

The Strokes property gets set and the signature is rendered

Actual Behavior

Nothing happens. If I set a breakpoint after setting the property, the strokes are empty.

Basic Information

SuNNjek commented 5 years ago

So it turns out this is because the SignaturePadCanvasView triggers an event in the renderer to set the strokes, but the control isn't rendered yet so there is no renderer. Is there any way to circumvent this?

abhay-prescriber-360 commented 5 years ago

I am facing the same Issue only difference is i am trying the same in iOS do we need to implement a custom renderer? because i have only added

signatureView.Strokes = newStrokes; line in my xaml.cs

jyt1902 commented 5 years ago

hello @SuNNjek Implement below code in UWP C#

Create canvas Load Event on Page constructor

 signatureCanvas.Loaded += signatureCanvas_LoadedAsync;
  private void signatureCanvas_LoadedAsync(object sender, RoutedEventArgs e)
        {
            try
            {
             Point[] points = GetStringToPoint(canvasPointsInString);
              signatureCanvas.LoadPoints(points);
}Catch(){}
}
 public Point[] GetStringToPoint(string canvasPointsString)
        {
            Point[] points = new Point[] { };
            try
            {
                if (!String.IsNullOrEmpty(canvasPointsString))
                {
                    int length = canvasPointsString.LastIndexOf(";");
                    string signature = canvasPointsString.Substring(0, length);
                    points = signature.Split(';').Select(x => x.Split(',')).Select(y => new Point(float.Parse(y[0]), float.Parse(y[1]))).ToArray();
                }
                return points;
            }
            catch (Exception ex)
            {

                return points;
            }

        }
SuNNjek commented 5 years ago

@jyt1902 My problem isn't converting the data to points, it's that the points don't get loaded because at the time I try to load them, I don't have a renderer.

jyt1902 commented 5 years ago

@SuNNjek check above updated code

breenbob commented 4 years ago

The missing link in @jyt1902's example was the SignaturePadView doesn't have a Loaded event, nor does Xamarin Forms. Not sure how he has implemented that, but I was able to do it using this method to get view life cycle events on views using effects. I added an instance of this effect to my SignaturePadView control, then set the Strokes property of the signature pad control inside the Loaded event to my saved JSON data (IEnumerable<IEnumerable>). Don't forget to unsubscribe to this event if adding programmatically instead of in Xaml. Thanks @jyt1902 for pointing me in the right direction.

evoynov commented 4 years ago

@breenbob please, share your complete example using ViewLifecycleEffect. I copied example from provided link and attached this way: <sigpad:SignaturePadView.Effects> <effects:ViewLifecycleEffect Loaded="ViewLifecycleEffect_OnLoaded" Unloaded="ViewLifecycleEffect_OnUnloaded"/> </sigpad:SignaturePadView.Effects>

but no messages raised on loading/unloading page with SignaturePadView.

Where did I miss valuable steps?

Welchen commented 4 years ago

I'm having the same problem. Is this project even being updated or monitored?

Welchen commented 4 years ago

@evoynov Do you know if you solved your problem of the messages not being raised? I'm having the same issue.

poloboc commented 3 years ago

Having same issue... Got it working by delaying the call to strokes setter.

        protected override void OnAppearing()
        {
                    base.OnAppearing();

                    Task.Run(()=> {
                        Thread.Sleep(1000);
                        SignatureView.Strokes = YOUR_COLLECTION_HERE;
                    });
         }