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
22.21k stars 1.74k forks source link

iOS - Incorrect Coordinates Returned by TapGestureRecognizer #19327

Closed kasanhoon closed 9 months ago

kasanhoon commented 10 months ago

Description

I am encountering an issue with the TapGestureRecognizer in a .NET 8 MAUI iOS environment.

The GetPosition() method from TappedEventArgs is supposed to return the relative coordinates of the touch point, but it's yielding incorrect values

MainPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="TapTest.MainPage">

    <Grid x:Name="TapAreaGrid" BackgroundColor="LightBlue">
        <Grid.GestureRecognizers>
            <TapGestureRecognizer Tapped="OnTapped" />
        </Grid.GestureRecognizers>
        <Image x:Name="ChildView" Source="dotnet_bot.png" WidthRequest="100" HeightRequest="100" BackgroundColor="LightPink" />        
    </Grid>

</ContentPage>

MainPage.xaml.cs

using System.Diagnostics;

namespace TapTest
{
    public partial class MainPage : ContentPage
    {        
        public MainPage()
        {
            InitializeComponent();
        }

        private void OnTapped(object sender, TappedEventArgs e)
        {
            var point = e.GetPosition(ChildView);
            Debug.Print($"point:{point}");
        }
    }
}

In the .NET 7 environment, this code correctly returns the relative coordinates of the touch point on ChildView. However, in the .NET 8 environment, specifically on iOS, it seems to return absolute coordinates instead of relative ones. This behavior appears to be isolated to the iOS platform in the .NET 8 environment.

Steps to Reproduce

  1. Create a default MAUI project.
  2. Replace the MainPage.xaml and MainPage.xaml.cs with the code provided above.
  3. Build & Execute the project on iOS.
  4. Check the log for the recorded touch coordinates.

Link to public reproduction project repository

No response

Version with bug

8.0.3

Is this a regression from previous behavior?

Yes, this used to work in .NET MAUI

Last version that worked well

7.0.101

Affected platforms

iOS

Affected platform versions

ios 17.0

Did you find any workaround?

No response

Relevant log output

If you touch the first pixel in the image, the log that appears will be as follows:

.net 7 result (ios)
[0:] point:{X=0 Y=0}

.net 8 result (ios)
[0:] point:{X=147 Y=270}
MartyIX commented 10 months ago

This issue looks very similar to the one I reported here #19329. Maybe these two are duplicates. I don't know.

MartyIX commented 10 months ago

@kasanhoon Would you possibly have a screenshot? If not, it's ok.

It's just that I've been debugging #19329 and my test sample is not OK because on macOS the image seems to be sized differently than on Windows. But the bug is there somewhere because pointer over grids does not work.

MartyIX commented 10 months ago

It seems to me that:

kasanhoon commented 10 months ago

@MartyIX You're right. Previously, even if the sender's child was passed as a parameter to GetPosition, it correctly returned relative coordinates. Now, this issue is happening only in the .NET 8 environment on iOS. The same code, when executed on iOS with .NET 7, returns the relative coordinates of the sender's child correctly.

<.net 7 ios screenshot> net7tap

<.net 8 ios screenshot> net8tap

The LightBlue area is the Grid that receives the tap event, and the LightPink area is the child image of the Grid. The size of the LightPink area is the same in both scenarios, with a width of 100px and a height of 100px. When the first pixel of the LightPink area is selected, .NET 7 correctly returns 0,0, but .NET 8 returns the distance from the origin point 0,0 of the LightBlue area.

MartyIX commented 10 months ago

So you mentioning that it works in .NET 7 and not in .NET 8 made check the source code and it seems to me that there is a difference on this line:

NET7

https://github.com/dotnet/maui/blob/5a1c4f6672541772f5e3334d22416c7a57cf7453/src/Controls/src/Core/Platform/GestureManager/GestureManager.iOS.cs#L199

NET8

https://github.com/dotnet/maui/blob/f9f840a32eea169c4bbbe2ab1bbb26ef2b2f953a/src/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.iOS.cs#L198

Notice that in .NET 8, the variable is not related to element. So it seems like a plausible explanation but I have not (yet?) verified whether changing the variable would fix the issue (and who knows what it can break).

ghost commented 10 months ago

We've added this issue to our backlog, and we will work to address it as time and resources allow. If you have any additional information or questions about this issue, please leave a comment. For additional info about issue management, please read our Triage Process.

mikeparker104 commented 9 months ago

Potential workaround pending updated package release.