Skip to content
18 changes: 18 additions & 0 deletions src/Controls/src/Core/Shell/ShellNavigationManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,24 @@ public static ShellNavigationState GetNavigationState(ShellItem shellItem, Shell
}
}

#if IOS || MACCATALYST
if (Shell.Current?.CurrentState?.Location is not null)
{
var currentRoute = Shell.Current?.CurrentState?.Location?.ToString();
if (!string.IsNullOrEmpty(currentRoute))
{
var currentPaths = new List<string>(currentRoute.Split('/'));
// Indices 0 and 1 of both routeStack and currentPaths are dummy/empty values
// The first meaningful route segment is at index 2.
if (currentPaths.Count == routeStack.Count && currentPaths.Count > 3 && currentPaths[2] == routeStack[2])
{
// Current route is same as the new route, so remove the last elements of the routeStack
routeStack.RemoveRange(3, routeStack.Count - 3);
}
}
}
#endif

if (routeStack.Count > 0)
routeStack.Insert(0, "/");

Expand Down
134 changes: 134 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue25599_1.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
namespace Maui.Controls.Sample.Issues;

[Issue(IssueTracker.Github, 25599_1, "Shell Navigating event shows identical Current and Target on tab click", PlatformAffected.iOS | PlatformAffected.macOS)]
public class Issue25599_1 : Shell
{
public Issue25599_1()
{
var tabBar = new TabBar();

var homeTab = new Tab
{
Title = "Home"
};
var homeShellContent = new ShellContent
{
ContentTemplate = new DataTemplate(() => new Issue25599_1MainPage()),
Route = "MainPage"
};
homeTab.Items.Add(homeShellContent);
tabBar.Items.Add(homeTab);

var settingsTab = new Tab
{
Title = "Settings"
};
var settingsShellContent = new ShellContent
{
ContentTemplate = new DataTemplate(() => new Issue25599_1DetailPage()),
Route = "DetailPage"
};
settingsTab.Items.Add(settingsShellContent);
tabBar.Items.Add(settingsTab);
Items.Add(tabBar);
}
}

public class Issue25599_1MainPage : ContentPage
{
Label navigatedLabel;
Label navigatingCurrentLabel;
Label navigatingTargetLabel;

public Issue25599_1MainPage()
{
var layout = new StackLayout
{
Padding = 20,
Spacing = 10
};

var button = new Button
{
Text = "Push Detail Page",
AutomationId = "PushButton"
};
button.Clicked += async (s, e) =>
{
await Navigation.PushAsync(new Issue25599_1DetailPage());
};

navigatingCurrentLabel = new Label
{
Text = "Navigating Current: Not triggered",
AutomationId = "MainPageNavigatingCurrentLabel",
FontSize = 12,
LineBreakMode = LineBreakMode.WordWrap
};

navigatingTargetLabel = new Label
{
Text = "Navigating Target: Not triggered",
AutomationId = "MainPageNavigatingTargetLabel",
FontSize = 12,
LineBreakMode = LineBreakMode.WordWrap
};

navigatedLabel = new Label
{
Text = "Navigated: Not triggered",
AutomationId = "MainPageNavigatedLabel",
FontSize = 12,
LineBreakMode = LineBreakMode.WordWrap
};

layout.Add(button);
layout.Add(navigatingCurrentLabel);
layout.Add(navigatingTargetLabel);
layout.Add(navigatedLabel);

Content = layout;
Title = "MainPage";

if (Application.Current?.MainPage is Issue25599_1 shell)
{
shell.Navigating += OnNavigating;
shell.Navigated += OnNavigated;
}
}

void OnNavigating(object sender, ShellNavigatingEventArgs e)
{
navigatingCurrentLabel.Text = $"{e.Current?.Location}";
navigatingTargetLabel.Text = $"{e.Target?.Location}";
}

void OnNavigated(object sender, ShellNavigatedEventArgs e)
{
navigatedLabel.Text = $"Navigated:\nPrevious: {e.Previous?.Location}\nCurrent: {e.Current?.Location}";
}
}

public class Issue25599_1DetailPage : ContentPage
{
public Issue25599_1DetailPage()
{
var layout = new StackLayout
{
Padding = 20,
Spacing = 10,
HeightRequest = 100
};

var popButton = new Button
{
Text = "Pop",
AutomationId = "PopButton"
};

layout.Add(popButton);
Content = layout;
Title = "DetailPage";

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#if TEST_FAILS_ON_WINDOWS && TEST_FAILS_ON_ANDROID // Clicking an already selected tab does not trigger navigation events on Windows or Android
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;

namespace Microsoft.Maui.TestCases.Tests.Issues;

public class Issue25599_1 : _IssuesUITest
{
public Issue25599_1(TestDevice testDevice) : base(testDevice)
{
}
public override string Issue => "Shell Navigating event shows identical Current and Target on tab click";

[Test]
[Category(UITestCategories.Shell)]
public void VerifyNavigatingEventOnTabReselection()
{
App.WaitForElement("PushButton");
App.Tap("PushButton");
App.WaitForElement("PopButton");
App.TapTab("Home");
var currentLabel = App.WaitForElement("MainPageNavigatingCurrentLabel");
var targetLabel = App.WaitForElement("MainPageNavigatingTargetLabel");
Assert.That(currentLabel.GetText(), Is.Not.EqualTo(targetLabel.GetText()));
}
}
#endif
Loading