Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
8 changes: 4 additions & 4 deletions eng/common/core-templates/job/job.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
parameters:
# Job schema parameters - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job
# Job schema parameters - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job
cancelTimeoutInMinutes: ''
condition: ''
container: ''
Expand All @@ -14,7 +14,7 @@ parameters:
workspace: ''
templateContext: {}

# Job base template specific parameters
# Job base template specific parameters
# See schema documentation - https://github.com/dotnet/arcade/blob/master/Documentation/AzureDevOps/TemplateSchema.md
# publishing defaults
artifacts: ''
Expand All @@ -33,7 +33,7 @@ parameters:
artifactPublishSteps: []
runAsPublic: false

# 1es specific parameters
# 1es specific parameters
is1ESPipeline: ''

jobs:
Expand Down Expand Up @@ -202,7 +202,7 @@ jobs:
TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/log'
continueOnError: true
condition: always()

- ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}:
- task: CopyFiles@2
displayName: Gather logs for publish to artifacts
Expand Down
3 changes: 3 additions & 0 deletions eng/common/internal/NuGet.config
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@
<clear />
<add key="dotnet-core-internal-tooling" value="https://pkgs.dev.azure.com/devdiv/_packaging/dotnet-core-internal-tooling/nuget/v3/index.json" />
</packageSources>
<packageSourceMapping>
<clear />
</packageSourceMapping>
</configuration>
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public override void ViewDidLoad()
{
bool accept = true;
var r = RendererForViewController(viewController);
if (r != null)
if (r is not null)
accept = ((IShellItemController)ShellItem).ProposeSection(r.ShellSection, false);

return accept;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@ void IAppearanceObserver.OnAppearanceChanged(ShellAppearance appearance)
ShellSection _shellSection;
bool _ignorePopCall;

bool _popRequested;

// When setting base.ViewControllers iOS doesn't modify the property right away.
// if you set base.ViewControllers to a new array and then retrieve base.ViewControllers
// iOS will return the previous array until the new array has been processed
Expand Down Expand Up @@ -109,7 +107,37 @@ public bool ShouldPopItem(UINavigationBar _, UINavigationItem __)
[Export("navigationBar:didPopItem:")]
[Internals.Preserve(Conditional = true)]
bool DidPopItem(UINavigationBar _, UINavigationItem __)
=> _popRequested || SendPop();
{
// Check for null references
if (_shellSection?.Stack is null || NavigationBar?.Items is null)
return true;

// Check if stacks are in sync
if (_shellSection.Stack.Count == NavigationBar.Items.Length)
return true;

var pages = _shellSection.Stack.ToList();

// Ensure we have enough pages and navigation items
if (pages.Count == 0 || NavigationBar.Items.Length == 0)
return true;

// Bounds check: ensure we have a valid index for pages array
int targetIndex = NavigationBar.Items.Length - 1;
if (targetIndex < 0 || targetIndex >= pages.Count)
return true;

_shellSection.SyncStackDownTo(pages[targetIndex]);

for (int i = pages.Count - 1; i >= NavigationBar.Items.Length; i--)
{
var page = pages[i];
if (page != null)
DisposePage(page);
}

return true;
}

internal bool SendPop()
{
Expand Down Expand Up @@ -393,7 +421,6 @@ protected virtual void OnNavigationRequested(object sender, NavigationRequestedE

protected virtual async void OnPopRequested(NavigationRequestedEventArgs e)
{
_popRequested = true;
var page = e.Page;
var animated = e.Animated;

Expand Down Expand Up @@ -434,7 +461,6 @@ async void ProcessPopToRoot()

protected virtual async void OnPopToRootRequested(NavigationRequestedEventArgs e)
{
_popRequested = true;
var animated = e.Animated;
var task = new TaskCompletionSource<bool>();
var pages = _shellSection.Stack.ToList();
Expand Down Expand Up @@ -527,12 +553,7 @@ void DisposePage(Page page, bool calledFromDispose = false)
_trackers.Remove(page);
}


var renderer = page.Handler;
if (renderer != null)
{
renderer.DisconnectHandler();
}
page?.DisconnectHandlers();
}

Element ElementForViewController(UIViewController viewController)
Expand Down Expand Up @@ -596,7 +617,6 @@ public override UIViewController[] PopToViewController(UIViewController viewCont
public override void PushViewController(UIViewController viewController, bool animated)
{
_pendingViewControllers = null;
_popRequested = false;
if (IsInMoreTab && ParentViewController is UITabBarController tabBarController)
{
tabBarController.MoreNavigationController.PushViewController(viewController, animated);
Expand All @@ -609,7 +629,6 @@ public override void PushViewController(UIViewController viewController, bool an

public override UIViewController PopViewController(bool animated)
{
_popRequested = true;
_pendingViewControllers = null;
if (IsInMoreTab && ParentViewController is UITabBarController tabBarController)
{
Expand Down
37 changes: 37 additions & 0 deletions src/Controls/src/Core/Shell/ShellSection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,43 @@ void IShellSectionController.SendInsetChanged(Thickness inset, double tabThickne
_lastTabThickness = tabThickness;
}

internal void SyncStackDownTo(Page page)
{
if (_navStack.Count <= 1)
{
throw new Exception("Nav Stack consistency error");
}

var oldStack = _navStack;

int index = oldStack.IndexOf(page);
_navStack = new List<Page>();

// Rebuild the stack up to the page that was passed in
// Since this now represents the current accurate stack
for (int i = 0; i <= index; i++)
{
_navStack.Add(oldStack[i]);
}

// Send Disappearing for all pages that are no longer in the stack
// This will really only SendDisappearing on the top page
// but we just call it on all of them to be sure
for (int i = oldStack.Count - 1; i > index; i--)
{
oldStack[i].SendDisappearing();
}

UpdateDisplayedPage();

for (int i = index + 1; i < oldStack.Count; i++)
{
RemovePage(oldStack[i]);
}

(Parent?.Parent as IShellController)?.UpdateCurrentState(ShellNavigationSource.Pop);
}

async void IShellSectionController.SendPopping(Task poppingCompleted)
{
if (_navStack.Count <= 1)
Expand Down
49 changes: 49 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue29798.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
namespace Maui.Controls.Sample.Issues;

[Issue(IssueTracker.Github, 29798, "Tab becomes blank after specific navigation pattern", PlatformAffected.iOS)]
public class Issue29798 : Shell
{
public Issue29798()
{
Routing.RegisterRoute(nameof(Issue29798Page), typeof(Issue29798Page));

Items.Add(new ShellContent()
{
Title = "Tab1",
Content = new ContentPage()
{
Title = "Test",
Content = new Button
{
Text = "Go to Page 2",
AutomationId = "GotoPage2",
Command = new Command(async () => await Current.GoToAsync(nameof(Issue29798Page)))
}
}
});

Items[0].Items.Add(new ShellContent()
{
Content = new ContentPage()
});
}
}

public class Issue29798Page : ContentPage
{
public Issue29798Page()
{
Title = "Page 2";
Content = new StackLayout
{
Children =
{
new Label
{
AutomationId = "Page2Label",
Text = "Welcome to Page 2"
}
}
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#if IOS
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;

namespace Microsoft.Maui.TestCases.Tests.Issues;

public class Issue29798 : _IssuesUITest
{
public Issue29798(TestDevice testDevice) : base(testDevice)
{
}

public override string Issue => "Tab becomes blank after specific navigation pattern";

[Test]
[Category(UITestCategories.Shell)]
public void TabShouldNotBeBlackAfterTabNavigation()
{
App.WaitForElement("GotoPage2");
App.Tap("GotoPage2");
App.WaitForElement("Page2Label");
App.Tap("Tab1");
App.WaitForElement("GotoPage2");
App.Tap("GotoPage2");
App.WaitForElement("Page2Label");
App.Tap("Tab1");
App.WaitForElement("GotoPage2");
}
}
#endif
2 changes: 1 addition & 1 deletion src/Core/src/Platform/iOS/MauiScrollView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public override void LayoutSubviews()
// For Right-To-Left (RTL) layouts, we need to adjust the content arrangement and offset
// to ensure the content is correctly aligned and scrolled. This involves a second layout
// arrangement with an adjusted starting point and recalculating the content offset.
if (_previousEffectiveUserInterfaceLayoutDirection != EffectiveUserInterfaceLayoutDirection)
if (_previousEffectiveUserInterfaceLayoutDirection is not null && _previousEffectiveUserInterfaceLayoutDirection != EffectiveUserInterfaceLayoutDirection)
{
if (EffectiveUserInterfaceLayoutDirection == UIUserInterfaceLayoutDirection.RightToLeft)
{
Expand Down
5 changes: 4 additions & 1 deletion src/Essentials/test/DeviceTests/Tests/Geocoding_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ public Geocoding_Tests()
ApplicationModel.Platform.MapServiceToken = "RJHqIE53Onrqons5CNOx~FrDr3XhjDTyEXEjng-CRoA~Aj69MhNManYUKxo6QcwZ0wmXBtyva0zwuHB04rFYAPf7qqGJ5cHb03RCDw1jIW8l";
#endif
}
#if !ANDROID

// Temporarily disabling this test on Windows due to consistent CI failures.
// See https://github.com/dotnet/maui/issues/30507 for tracking re-enablement.
#if !ANDROID && !WINDOWS
[Theory]
[InlineData(47.673988, -122.121513)]
public async Task Get_Placemarks_LatLong(double latitude, double longitude)
Expand Down
Loading