dotnet / maui

.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.
https://dot.net/maui
MIT License
21.87k stars 1.69k forks source link

GraphicsView does not call Drawable's Draw() after each Invalidate on iOS #9595

Open maiiaKey opened 1 year ago

maiiaKey commented 1 year ago

Description

We are creating a custom Signature Pad control in Maui using GraphicsView as a basis and then we need to consume this control in native .Net6 iOS, Android and Windows projects. Since we want to display the stroke as soon as user draws it, we are calling GraphicsView.Invalidate() method each 50ms.

Observed behavior:

Android and Windows works as designed: the stroke appears as soon as user draws it However on iOS the stroke only appears after the user ends the touch.

Expected behavior:

The control works the same way on iOS as on Windows and Android.

Steps to Reproduce

Attaching a repro sample (contains a Maui library project and 3 native app projects) SignaturePadIos.zip

Version with bug

6.0.400

Last version that worked well

Unknown/Other

Affected platforms

iOS

Affected platform versions

iOS 15

Did you find any workaround?

No response

Relevant log output

No response

ghost commented 1 year ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

WebGoose commented 1 year ago

I am having a similar issue (although I swear it worked a month ago). I have a few graphicsviews in my app and only about 75% of them now call the draw method on Invalidate in iOS, so some controls just don't draw at all.

The controls work perfectly in Android and call Draw just fine.

Dokug commented 1 year ago

I have a similar issue, where an IDrawable is supposed to be refreshed constantly with a timer:

    var timer = new System.Timers.Timer(50);
    timer.Elapsed += new System.Timers.ElapsedEventHandler(UpdateDrawable);
    timer.Start();

    //UpdateDrawable just sets a view values and invalidates the drawable
    private void UpdateDrawable(object? sender, EventArgs e)
    {
         //[...]
                DisplayView.Invalidate(); //DisplayView is of type GraphicsView
    }

On Windows this works as expected and well, on iOS this only works if UpdateDrawable() is called from a Button or any other "finished" UI interaction.

rdessart commented 1 year ago

You need to invoke a dispatcher into your ElapsedEvent:

Application.Current.MainPage.Dispatcher.Dispatch(() =>
{
    DisplayView.Invalidate();
});

To force the Invalidate call to be called on the UI Thread