Skip to content

Commit fb538bf

Browse files
Fix-33351-Made changes to trigger page appearing events before platform navigation to ensure Shell TabBar visibility is applied correctly during multi-level back navigation.
1 parent 6c123d7 commit fb538bf

8 files changed

Lines changed: 218 additions & 3 deletions

File tree

src/Controls/src/Core/Shell/ShellSection.cs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -844,10 +844,21 @@ protected virtual async Task OnPopToRootAsync(bool animated)
844844
RequestType = NavigationRequestType.PopToRoot
845845
};
846846

847-
InvokeNavigationRequest(args);
847+
PresentedPageDisappearing();
848848
var oldStack = _navStack;
849849
_navStack = new List<Page> { null };
850850

851+
// NOTE:
852+
// We intentionally raise PresentedPageAppearing (and thus SendPageAppearing/OnAppearing)
853+
// before issuing the platform navigation request and awaiting its completion. This matches
854+
// the behavior used for single-level Pop navigation and keeps Shell lifecycle events
855+
// consistent across navigation patterns. At this point the root page may not yet be
856+
// visually presented by the native stack (the pop-to-root animation can still be in
857+
// progress), but Shell-level state (e.g., tab bar visibility) must already be updated
858+
// so the platform reads the correct value when it commits the native navigation.
859+
PresentedPageAppearing();
860+
InvokeNavigationRequest(args);
861+
851862
if (args.Task != null)
852863
await args.Task;
853864

@@ -856,11 +867,14 @@ protected virtual async Task OnPopToRootAsync(bool animated)
856867

857868
for (int i = 1; i < oldStack.Count; i++)
858869
{
859-
oldStack[i].SendDisappearing();
870+
// RemovePage is called for all pages. SendDisappearing is only called for
871+
// intermediate pages; the top page's disappearing event was already fired
872+
// by PresentedPageDisappearing() above to avoid duplicate lifecycle events.
873+
if (i < oldStack.Count - 1)
874+
oldStack[i].SendDisappearing();
860875
RemovePage(oldStack[i]);
861876
}
862877

863-
PresentedPageAppearing();
864878
}
865879

866880
protected virtual Task OnPushAsync(Page page, bool animated)
31 KB
Loading
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
namespace Maui.Controls.Sample.Issues;
2+
3+
[Issue(IssueTracker.Github, 33351, "Changing Shell Tab Visibility when navigating back multiple pages ignores Shell Tab Visibility", PlatformAffected.All)]
4+
public class Issue33351 : Shell
5+
{
6+
public Issue33351()
7+
{
8+
Routing.RegisterRoute("Issue33351Page1", typeof(Issue33351Page1));
9+
Routing.RegisterRoute("Issue33351Page2", typeof(Issue33351Page2));
10+
11+
var tabBar = new TabBar
12+
{
13+
Items =
14+
{
15+
new MyTab
16+
{
17+
Title = "Tab 1",
18+
ContentTemplate = new DataTemplate(() => new Issue33351MainPage())
19+
},
20+
new ShellContent
21+
{
22+
Title = "Tab 2",
23+
ContentTemplate = new DataTemplate(() => new Issue33351SecondTabPage())
24+
}
25+
}
26+
};
27+
28+
Items.Add(tabBar);
29+
}
30+
31+
class MyTab : ShellContent
32+
{
33+
protected override void OnAppearing()
34+
{
35+
base.OnAppearing();
36+
37+
if (this.Parent != null)
38+
Shell.SetTabBarIsVisible(this.Parent, true);
39+
40+
Shell.Current.Navigating -= OnShellNavigating;
41+
Shell.Current.Navigating += OnShellNavigating;
42+
}
43+
44+
protected override void OnDisappearing()
45+
{
46+
base.OnDisappearing();
47+
48+
Shell.Current.Navigating -= OnShellNavigating;
49+
}
50+
51+
void OnShellNavigating(object sender, ShellNavigatingEventArgs e)
52+
{
53+
if (this.Parent != null)
54+
Shell.SetTabBarIsVisible(this.Parent, false);
55+
}
56+
}
57+
58+
class Issue33351MainPage : ContentPage
59+
{
60+
public Issue33351MainPage()
61+
{
62+
Title = "Main Page";
63+
AutomationId = "RootPage";
64+
65+
var statusLabel = new Label
66+
{
67+
AutomationId = "TabBarVisibleLabel",
68+
Text = "Tab Bar Visible"
69+
};
70+
71+
var navigateButton = new Button
72+
{
73+
AutomationId = "PushPage1Button",
74+
Text = "Go to Page 1",
75+
HorizontalOptions = LayoutOptions.Fill
76+
};
77+
78+
navigateButton.Clicked += async (s, e) =>
79+
{
80+
await Shell.Current.GoToAsync("Issue33351Page1");
81+
};
82+
83+
Content = new VerticalStackLayout
84+
{
85+
Padding = new Thickness(20),
86+
Spacing = 20,
87+
Children = { statusLabel, navigateButton }
88+
};
89+
}
90+
}
91+
92+
class Issue33351Page1 : ContentPage
93+
{
94+
public Issue33351Page1()
95+
{
96+
Title = "Page 1";
97+
98+
var statusLabel = new Label
99+
{
100+
AutomationId = "TabBarHiddenLabel",
101+
Text = "Tab Bar Hidden"
102+
};
103+
104+
var navigateButton = new Button
105+
{
106+
AutomationId = "PushPage2Button",
107+
Text = "Go to Page 2",
108+
HorizontalOptions = LayoutOptions.Fill
109+
};
110+
111+
navigateButton.Clicked += async (s, e) =>
112+
{
113+
await Shell.Current.GoToAsync("Issue33351Page2");
114+
};
115+
116+
Content = new VerticalStackLayout
117+
{
118+
Padding = new Thickness(20),
119+
Spacing = 20,
120+
Children = { statusLabel, navigateButton }
121+
};
122+
}
123+
}
124+
125+
class Issue33351Page2 : ContentPage
126+
{
127+
public Issue33351Page2()
128+
{
129+
Title = "Page 2";
130+
AutomationId = "Page2";
131+
132+
var statusLabel = new Label
133+
{
134+
AutomationId = "TabBarHiddenLabel2",
135+
Text = "Tab Bar Hidden"
136+
};
137+
138+
var popToRootButton = new Button
139+
{
140+
AutomationId = "PopToRootButton",
141+
Text = "Go Back (../..)",
142+
HorizontalOptions = LayoutOptions.Fill
143+
};
144+
145+
popToRootButton.Clicked += async (s, e) =>
146+
{
147+
await Shell.Current.GoToAsync("../..");
148+
};
149+
150+
Content = new VerticalStackLayout
151+
{
152+
Padding = new Thickness(20),
153+
Spacing = 20,
154+
Children = { statusLabel, popToRootButton }
155+
};
156+
}
157+
}
158+
159+
class Issue33351SecondTabPage : ContentPage
160+
{
161+
public Issue33351SecondTabPage()
162+
{
163+
Title = "Tab 2";
164+
Content = new Label { Text = "Tab 2" };
165+
}
166+
}
167+
}
10.8 KB
Loading
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using NUnit.Framework;
2+
using UITest.Appium;
3+
using UITest.Core;
4+
5+
namespace Microsoft.Maui.TestCases.Tests.Issues;
6+
7+
public class Issue33351 : _IssuesUITest
8+
{
9+
public Issue33351(TestDevice testDevice) : base(testDevice)
10+
{
11+
}
12+
13+
public override string Issue => "Changing Shell Tab Visibility when navigating back multiple pages ignores Shell Tab Visibility";
14+
15+
[Test]
16+
[Category(UITestCategories.Shell)]
17+
public void TabBarVisibilityAfterMultiLevelPopToRoot()
18+
{
19+
App.WaitForElement("Tab 1");
20+
App.Tap("Tab 1");
21+
22+
App.WaitForElement("PushPage1Button");
23+
App.Tap("PushPage1Button");
24+
25+
App.WaitForElement("PushPage2Button");
26+
App.Tap("PushPage2Button");
27+
28+
App.WaitForElement("PopToRootButton");
29+
App.Tap("PopToRootButton");
30+
App.WaitForElement("TabBarVisibleLabel");
31+
32+
VerifyScreenshot();
33+
}
34+
}
10.7 KB
Loading
40.5 KB
Loading
29.8 KB
Loading

0 commit comments

Comments
 (0)