Skip to content

Commit

Permalink
Fixed Net 8: Page and control Unloaded events firing on iOS when navi…
Browse files Browse the repository at this point in the history
…gating to another page (dotnet#25852)

* Fix included and UI test case added

* Snapshot added for windows platform.

* Test case modified and committed

* Comments added for my fix.

* comments modified

* - fix up test and extension a bit

---------

Co-authored-by: Karthik Raja <[email protected]>
Co-authored-by: Shane Neuville <[email protected]>
  • Loading branch information
3 people authored Dec 17, 2024
1 parent ff62205 commit 7291b48
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 2 deletions.
72 changes: 72 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue21916.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
namespace Maui.Controls.Sample.Issues
{
[Issue(IssueTracker.Github, 21916, "Page and control Unloaded events firing on iOS when navigating to another page", PlatformAffected.iOS)]
public class Issue21916 : Shell
{
public Issue21916()
{
CurrentItem = new Issue21916_MainPage();
}

public class Issue21916_MainPage : ContentPage
{
int mainPageLoadedCount = 0;
int mainPageUnloadedCount = 0;
Label label;
bool isNavigated;
public Issue21916_MainPage()
{
var stack = new StackLayout();
label = new Label();
var Button = new Button();
Button.Text = "Click to navigate new page";
Button.AutomationId = "Button";
Button.Clicked += Clicked;
stack.Children.Add(Button);
stack.Children.Add(label);
this.Content = stack;
this.Loaded += MainPage_Loaded;
this.Unloaded += MainPage_UnLoaded;
}

private async void Clicked(object sender, EventArgs e)
{
isNavigated = true;
await Navigation.PushAsync(new Issue21916_NewPage());
}

private void MainPage_UnLoaded(object sender, EventArgs e)
{
mainPageUnloadedCount++;
}

private void MainPage_Loaded(object sender, EventArgs e)
{
if (isNavigated)
{
mainPageLoadedCount++;
label.Text = $"Unloaded event triggered {mainPageUnloadedCount} times\nLoaded event triggered {mainPageLoadedCount} times";
}
}
}

public class Issue21916_NewPage : ContentPage
{
public Issue21916_NewPage()
{
var stack = new StackLayout();
var Button = new Button();
Button.Text = "Click to navigate main page";
Button.AutomationId = "Button";
Button.Clicked += Clicked;
stack.Children.Add(Button);
this.Content = stack;
}

private void Clicked(object sender, EventArgs e)
{
Shell.Current.GoToAsync("..");
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#if !ANDROID && !MACCATALYST
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;

namespace Microsoft.Maui.TestCases.Tests.Issues
{
public class Issue21916 : _IssuesUITest
{
public Issue21916(TestDevice testDevice) : base(testDevice)
{
}

public override string Issue => "Page and control Unloaded events firing on iOS when navigating to another page";

[Test]
[Category(UITestCategories.Shell)]
public void Shell_Issue21916()
{
App.WaitForElement("Button");
App.Click("Button");
App.WaitForElement("Button");
App.Click("Button");
VerifyScreenshot();
}
}
}
#endif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 6 additions & 2 deletions src/Core/src/Platform/iOS/ViewExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,9 @@ internal static IDisposable OnLoaded(this UIView uiView, Action action)

void OnLifeCycleEventsMovedToWindow(object? sender, EventArgs e)
{
OnLoadedCheck(null);
//The MovedToWindow fires multiple times during navigation animations, causing repeated OnLoadedCheck calls.
//BeginInvokeOnMainThread ensures OnLoadedCheck executes after all window transitions are complete.
uiView.BeginInvokeOnMainThread(() => OnLoadedCheck(null));
}
}
else
Expand Down Expand Up @@ -728,7 +730,9 @@ internal static IDisposable OnUnloaded(this UIView uiView, Action action)

void OnLifeCycleEventsMovedToWindow(object? sender, EventArgs e)
{
UnLoadedCheck();
//The MovedToWindow fires multiple times during navigation animations, causing repeated UnLoadedCheck calls.
//BeginInvokeOnMainThread ensures UnLoadedCheck executes after all window transitions are complete.
uiView.BeginInvokeOnMainThread(UnLoadedCheck);
}
}

Expand Down

0 comments on commit 7291b48

Please sign in to comment.