Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[iOS] Fix for NullReferenceException in WillMoveToParentViewController When Removing Page During Navigation #27275

Merged
merged 6 commits into from
Jan 25, 2025
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1322,6 +1322,11 @@ public override void WillMoveToParentViewController(UIViewController parent)
{
base.WillMoveToParentViewController(parent);

if (_tracker is null)
{
return;
}

if (parent is null)
{
_tracker.CollectionChanged -= TrackerOnCollectionChanged;
Expand Down
62 changes: 62 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue25726.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
namespace Maui.Controls.Sample.Issues;

[XamlCompilation(XamlCompilationOptions.Compile)]
[Issue(IssueTracker.Github, 25726, "NullReferenceException in WillMoveToParentViewController When Removing Page During Navigation on iOS", PlatformAffected.iOS)]
public partial class Issue25726 : NavigationPage
{
public Issue25726()
{
// Directly push Page 1
PushAsync(CreatePage("Page 1", "Navigate to Page 2", "NavigateToPage2Button", CreatePage2));
}

// Common method to create pages with button and navigation functionality
private ContentPage CreatePage(string title, string buttonText, string automationId, Func<ContentPage> nextPageCreator)
{
return new ContentPage
{
Title = title,
Content = new Button
{
Text = buttonText,
AutomationId = automationId,
Command = new Command(async () =>
{
var nextPage = nextPageCreator();
await PushAsync(nextPage);
})
}
};
}

private ContentPage CreatePage2()
{
var page2 = CreatePage("Page 2", "Navigate to Page 3", "NavigateToPage3Button", CreatePage3);


page2.Content = new Button
{
Text = "Navigate to Page 3",
AutomationId = "NavigateToPage3Button",
Command = new Command(() =>
{
var page3 = CreatePage3();
PushAsync(page3);

// Manipulate the stack after navigating to Page 3
Navigation.RemovePage(Navigation.NavigationStack[^2]);
})
};

return page2;
}

private ContentPage CreatePage3()
{
return new ContentPage
{
Title = "Page 3",
Content = new Label { Text = "This is Page 3", AutomationId = "Page3Label" }
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;

namespace Microsoft.Maui.TestCases.Tests.Issues;

internal class Issue25726 : _IssuesUITest
{
#if ANDROID || WINDOWS
private const string BackButtonIdentifier = "";
#else
private const string BackButtonIdentifier = "Page 1";
#endif

public Issue25726(TestDevice device) : base(device) { }

public override string Issue => "NullReferenceException in WillMoveToParentViewController When Removing Page During Navigation on iOS";

[Test]
[Category(UITestCategories.Navigation)]
public void NavigationShouldNotCrashWhenRemovingPageDuringNavigation()
{
App.WaitForElement("NavigateToPage2Button");
App.Tap("NavigateToPage2Button");

App.WaitForElement("NavigateToPage3Button");
App.Tap("NavigateToPage3Button");

// Ensure the label on Page 3 is present to verify navigation completed successfully
// If the app crashes during navigation, the test will fail before reaching this line.
App.WaitForElement("Page3Label");

App.TapBackArrow(BackButtonIdentifier);

// Ensure we navigate back to Page 1 successfully
App.WaitForElement("NavigateToPage2Button");
}
}
Loading