unoplatform / uno

Open-source platform for building cross-platform native Mobile, Web, Desktop and Embedded apps quickly. Create rich, C#/XAML, single-codebase apps from any IDE. Hot Reload included! 90m+ NuGet Downloads!!
https://platform.uno
Apache License 2.0
9.04k stars 733 forks source link

[MacCatalyst, iOS] Support for mouse over states #12467

Open TopperDEL opened 1 year ago

TopperDEL commented 1 year ago

Current behavior

The following PointerEvents do not work on MacCatalyst:

Expected behavior

The events work as expected.

How to reproduce it (as minimally and precisely as possible)

Here is a githubrepo: https://github.com/TopperDEL/MacPointerEvents

The same is attached as Zip-File: MacPointerEvents.zip

Workaround

None yet, unfortunately

Works on UWP/WinUI

Yes

Environment

Uno.WinUI / Uno.WinUI.WebAssembly / Uno.WinUI.Skia

NuGet package version(s)

4.8.24

Affected platforms

Mac Catalyst

IDE

Visual Studio for Mac

IDE version

17.5.6 build 3

Relevant plugins

No response

Anything else we need to know?

I highly need this for an app. If there is an easy way to deploy to "MacOS" instead of "MacCatalyst" as a workaround, I would be glad to know how to do it.

Youssef1313 commented 1 year ago

https://github.com/unoplatform/uno/issues/8788

TopperDEL commented 1 year ago

Is this something I could tackle on my own? If yes, may someone guide me where I could start? This is a show-stopper on my end, so I would love to get a fix asap and am willing to help resolve this. Thank you!

dr1rrb commented 1 year ago

On iOS (and mac catalyst) we support only "touch" inputs and we "inject" the PointerEnter when the finger starts to touch the screen (https://github.com/unoplatform/uno/blob/master/src/Uno.UI/UI/Xaml/UIElement.Pointers.iOS.cs#L129).

Adding support for "hovering" requires:

  1. Listen to native events (e.g. https://developer.apple.com/documentation/uikit/pointer_interactions);
  2. Raise the event accordingly, basically invoke the OnNativePointerEnter(args) and OnNativePointerExited(args);
  3. Most importantly make sure to maintain internal state to avoid conflict with the "injected" pointer-enter for touch and ensure a valid event sequence. For instance on Android, when you hover an element, it will raise exited on press. So simply raising the managed event from native events would have result to:
    • Enter
    • Move*
    • EXITED <<== We have to mute this native event
    • INJECTED ENTER <<== We don't have to inject event since already "entered"
    • Down
    • Move*
    • Up
    • INJECTED EXITED <<== We don't have to inject event since pointer is still hover
    • ENTER <<== We have to mute this native event
    • Move*
  4. Consider the "cancelled" to make sure the UI is not stuck in a "pressed" state
  5. Consider the "implicit capture" of iOS (as soon as a finger touches the screen, all pointers are forwarded to the same element, no matter if pointer has moved hover another element), so we raise enter/exited properly even if pressed (already partially supported).
  6. Make sure the hover visual states are defined in control templates (in time being we were not adding all visual-states on all platforms to avoid the cost of the creation of those state that was not used).

Definitely not a simple one :)

GitHub
uno/UIElement.Pointers.iOS.cs at master · unoplatform/uno
Build Mobile, Desktop and WebAssembly apps with C# and XAML. Today. Open source and professionally supported. - uno/UIElement.Pointers.iOS.cs at master · unoplatform/uno
Apple Developer Documentation
Pointer interactions | Apple Developer Documentation
Support pointer interactions in your custom controls and views.
TopperDEL commented 1 year ago

Thanks! I'll see if I can tackle this after the holidays. But it really sounds though - if anyone can solve this before me would be absolutely ok. :) I'll comment here whenever I start.

TopperDEL commented 11 months ago

I just came back to the current state of Uno in Mac Catalyst. This issue still persists. I discussed this with @jeromelaban in this discussion.

This part is crucial to my app but I'm unable to fix the issue as discussed above.

May I ask for a higher prioritization of this issue? Thank you!