Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@cat0363
Copy link
Contributor

@cat0363 cat0363 commented Aug 9, 2023

This PR fixes the problem that the call does not return when the ScrollToAsync method is
called at the timing of OnNavigatedTo, OnAppearing events.

Description of Change

If the ScrollToAsync method is called in the OnNavigatedTo or OnAppearing event, the Handler is null
at this point, so I added code to handle the scroll request in the Loaded event.

[src\Controls\src\Core\ScrollView\ScrollView.cs]

void OnScrollToRequested(ScrollToRequestedEventArgs e)
{
    CheckTaskCompletionSource();
    ScrollToRequested?.Invoke(this, e);

    if (Handler is not null)
    {
        Handler.Invoke(nameof(IScrollView.RequestScrollTo), ConvertRequestMode(e).ToRequest());
    }
    else
    {
        Loaded += (sender, args) =>
        {
            Dispatcher.Dispatch(() =>
            {
                Handler?.Invoke(nameof(IScrollView.RequestScrollTo), ConvertRequestMode(e).ToRequest());
            });
        };
    }
}

On Windows, the ViewChanged event doesn't fire until the ScrollView's position is updated, so I added code to call the ScrollFinish method if the requested scroll position is the same as the current scroll position when processing a scroll request.

[src\Core\src\Handlers\ScrollView\ScrollViewHandler.Windows.cs]

public static void MapRequestScrollTo(IScrollViewHandler handler, IScrollView scrollView, object? args)
{
    if (args is ScrollToRequest request)
    {
        if (handler.PlatformView.HorizontalOffset == request.HorizontalOffset &&
            handler.PlatformView.VerticalOffset == request.VerticalOffset)
        {
            handler.VirtualView.ScrollFinished();
        }
        else
        {
            handler.PlatformView.ChangeView(request.HorizontalOffset, request.VerticalOffset, null, request.Instant);
        }
    }
}

Issues Fixed

Fixes #15387

I used the following code for testing.

https://github.com/cat0363/Maui-IssueScrollToAsync2.git

The following log is output to the Editor before and after calling the ScrollToAsync method.

    txtLog.Text += ("Before ScrollToAsync" + Environment.NewLine);
    await svTestItem.ScrollToAsync(0, 200, false);
    txtLog.Text += ("After ScrollToAsync" + Environment.NewLine);

Below is the execution result.

[iOS]

[OnNavigatedTo] [OnAppearing]
iPhone.14.iOS.16.4.2023-08-09.12-08-31.mp4
iPhone.14.iOS.16.4.2023-08-09.12-43-59.mp4

[Android]

[OnNavigatedTo] [OnAppearing]
Android.Emulator.-.pixel_2_-_api_30_5554.2023-08-09.12-11-58.mp4
Android.Emulator.-.pixel_2_-_api_30_5554.2023-08-09.12-47-30.mp4

[Windows]

[OnNavigatedTo] [OnAppearing]
2023-08-09.12-05-21.mp4
2023-08-09.12-26-53.mp4

You can see that the ScrollToAsync method call is returned in the OnNavigatedTo event and OnAppearing event on all platforms.
The log is already displayed when the screen is started, but it is the log when the ScrollToAsync method is called in the OnNavigateTo event and OnAppearing event that is called when the screen is displayed for the first time.

@ghost ghost added the community ✨ Community Contribution label Aug 9, 2023
@ghost
Copy link

ghost commented Aug 9, 2023

Hey there @cat0363! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed.

@jfversluis
Copy link
Member

jfversluis commented Aug 9, 2023

/azp run MAUI-UITests-public

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@cat0363
Copy link
Contributor Author

cat0363 commented Aug 10, 2023

I wrote the unit test code.
This is my first time writing test code that uses NavigationPage, so if there are any mistakes, could you point them out?

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@samhouts samhouts added this to the Under Consideration milestone Aug 15, 2023
@Eilon Eilon added the area-layout StackLayout, GridLayout, ContentView, AbsoluteLayout, FlexLayout, ContentPresenter label Aug 15, 2023
@rmarinho
Copy link
Member

@cat0363 can you get the latest changes from main please? I think this could have been fixed by 5af60d3

@cat0363
Copy link
Contributor Author

cat0363 commented Aug 22, 2023

@rmarinho , Thank you for letting me know.
I got the latest for main and verified it.

Below are the verification results.

[iOS]

[OnNavigatedTo] [OnAppearing]
iPhone.14.iOS.16.4.2023-08-22.11-34-15.mp4
iPhone.14.iOS.16.4.2023-08-22.11-37-28.mp4

On iOS, calling the ScrollToAsync method in the OnNavigatedTo and OnAppearing events when the screen is first displayed does not work as intended.

[Android]

[OnNavigatedTo] [OnAppearing]
Android.Emulator.-.pixel_2_-_api_30_5554.2023-08-22.10-47-28.mp4
Android.Emulator.-.pixel_2_-_api_30_5554.2023-08-22.10-42-11.mp4

On Android, calling the ScrollToAsync method in the OnNavigatedTo and OnAppearing events when the screen is first displayed does not work as intended.

[Windows]

[OnNavigatedTo] [OnAppearing]
2023-08-22.10-28-36.mp4
2023-08-22.10-26-18.mp4

On Windows, calling the ScrollToAsync method in the OnNavigatedTo and OnAppearing events when the screen is first displayed does not work as intended. Calling the ScrollToAsync method in the OnAppearing event when transitioning from another screen does not work as intended.

All in all, the result was not what I expected.

The PR I created shows that the ScrollToAsync method works as intended even when the screen is displayed for the first time.
I expected the ScrollToAsync method to work as intended when the screen first appeared, and not when it was navigated to from another screen.

@samhouts samhouts added the stale Indicates a stale issue/pr and will be closed soon label Sep 11, 2023
@cat0363
Copy link
Contributor Author

cat0363 commented Sep 12, 2023

With 5af60d3, the problem is still there. Is there any other solution?
A stale tag was added, but the problem is still there.

@cat0363
Copy link
Contributor Author

cat0363 commented Dec 15, 2023

Even with .NET 8, the problem continues to occur.
If you wait synchronously for the ScrollToAsync method inside the OnNavigatedTo event, it will remain blocked.

@hartez hartez requested review from rmarinho and removed request for hartez January 10, 2024 21:08
@cat0363
Copy link
Contributor Author

cat0363 commented Jan 12, 2024

@rmarinho , As far as I investigated, the method call does not finish only if the ScrollToAsync method is called when the ScrollView's size is not determined.
Calling the ScrollToAsync method when the height and width of the ScrollView are 0 and not determined will fail.
I hope this will give you a hint on how to fix it.

@rmarinho
Copy link
Member

Can you rebase on main I will pull and take a look

@cat0363 cat0363 requested a review from a team as a code owner January 15, 2024 04:33
@cat0363 cat0363 requested a review from tj-devel709 January 15, 2024 04:33
@cat0363
Copy link
Contributor Author

cat0363 commented Jan 15, 2024

Modify the previous code and upload it again.
Please wait a moment now.

@cat0363
Copy link
Contributor Author

cat0363 commented Jan 15, 2024

I made some changes today, but I'll revert to the latest version of main.
After applying the latest version of main, both Android and iOS no longer wait forever after calling the ScrollToAsync method, but on Android, the screen does not scroll correctly the first time it is displayed. On Android, the scroll position remains at (0,0).

It's probably the same problem as the one below.
#14594

@cat0363
Copy link
Contributor Author

cat0363 commented Jan 16, 2024

The latest code verification results for main are listed below.

On Windows, if the call to the ScrollToAsync method does not change the position of the ScrollBar, the call to the ScrollToAsync method does not finish. Therefore, in addition to the latest source code for main, you will need:

[src\Core\src\Handlers\ScrollView\ScrollViewHandler.Windows.cs]

public static void MapRequestScrollTo(IScrollViewHandler handler, IScrollView scrollView, object? args)
{
    if (args is ScrollToRequest request)
    {
        if (handler.PlatformView.HorizontalOffset == request.HorizontalOffset &&
            handler.PlatformView.VerticalOffset == request.VerticalOffset)
        {
            handler.VirtualView.ScrollFinished();
        }
        else
        {
            handler.PlatformView.ChangeView(request.HorizontalOffset, request.VerticalOffset, null, request.Instant);
        }
    }
}

On iOS, calling the ScrollToAsync method within the OnNavigatedTo, OnAppearing events works as intended.

On Android, calling the ScrollToAsync method within the OnNavigatedTo, OnAppearing event does not work as intended only on first appearance.

@Eilon Eilon removed the area-layout StackLayout, GridLayout, ContentView, AbsoluteLayout, FlexLayout, ContentPresenter label May 14, 2024
@PureWeen PureWeen removed this from the Under Consideration milestone Aug 2, 2024
@PureWeen
Copy link
Member

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 3 pipeline(s).

@jfversluis jfversluis added this to the .NET 10 SR1 milestone Oct 21, 2025
@PureWeen PureWeen modified the milestones: .NET 10 SR1, .NET 10.0 SR2 Nov 4, 2025
@jfversluis
Copy link
Member

/rebase

…crollToAsync method call

# Conflicts:
#	src/Controls/src/Core/ScrollView/ScrollView.cs
@jfversluis
Copy link
Member

/azp run MAUI-public

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@jfversluis
Copy link
Member

/azp run MAUI-DeviceTests-public

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@jfversluis
Copy link
Member

The test seems to fail on Android and that even crashes the test suite. I think the fix is good though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-controls-scrollview ScrollView community ✨ Community Contribution stale Indicates a stale issue/pr and will be closed soon

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Calling ScrollView ScrollToAsync in OnNavigatedTo event or OnAppearing event does not return.

7 participants