Skip to content

[iOS/Mac Catalyst 26] Fix NavigationPage content not extending behind floating glass tab bar#35523

Merged
kubaflo merged 5 commits into
dotnet:inflight/currentfrom
SyedAbdulAzeemSF4852:fix-35490
Jun 5, 2026
Merged

[iOS/Mac Catalyst 26] Fix NavigationPage content not extending behind floating glass tab bar#35523
kubaflo merged 5 commits into
dotnet:inflight/currentfrom
SyedAbdulAzeemSF4852:fix-35490

Conversation

@SyedAbdulAzeemSF4852

Copy link
Copy Markdown
Contributor

Note

Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!

Issue Details

  • On iOS 26, pages inside a NavigationPage hosted in a TabbedPage do not extend behind the new floating glass tab bar, leaving a white gap between the page content and the tab bar.

Root Cause

  • On iOS 26, the tab bar changed from a solid bar to a floating glass overlay. ParentingViewController.ViewWillAppear was assigning EdgesForExtendedLayout = UIRectEdge.None for opaque navigation bars, which prevented content from extending under the tab bar — leaving a white gap between the page content and the new floating glass bar.

Description of Change

  • Updated NavigationRenderer to extend content layout behind the floating tab bar when running on iOS/Mac Catalyst 26+ and the tab bar is visible, preventing content from being clipped.

Issues Fixed

Fixes #35490

Validated the behaviour in the following platforms

  • Windows
  • Android
  • iOS
  • Mac

Output

Before After
Without_Fix.mov
With_Fix.mov

@github-actions

github-actions Bot commented May 19, 2026

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 35523

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 35523"

@dotnet-policy-service dotnet-policy-service Bot added the community ✨ Community Contribution label May 19, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Hey there @@SyedAbdulAzeemSF4852! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed.

@dotnet-policy-service dotnet-policy-service Bot added the partner/syncfusion Issues / PR's with Syncfusion collaboration label May 19, 2026
@kubaflo

kubaflo commented May 19, 2026

Copy link
Copy Markdown
Contributor

/review -b feature/regression-check -p ios

@MauiBot MauiBot added s/agent-review-incomplete s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels May 19, 2026
@corne-ac

Copy link
Copy Markdown

Good day,
Jumping in here to say, I tested it on my reproduction project shared in the original issue, and the fix worked, but for some reason in our main project that I found the issue, it doesnt, tried for a while now and am so unsure of why... did complete cleans of our project, removed all styling, delete bin obj, but no success with the artifacts from this PR (this could truly just be some issue in our project, but dont want to claim this PR doesnt fix the issue, seeing that it does work in the repro proj).

If anyone else perhaps wants to test and confirm that this fix works!

@dotnet dotnet deleted a comment from MauiBot May 20, 2026
@kubaflo

kubaflo commented May 20, 2026

Copy link
Copy Markdown
Contributor

/review -b feature/regression-check -p ios

@kubaflo

kubaflo commented May 21, 2026

Copy link
Copy Markdown
Contributor

/azp run maui-pr-uitests

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@dotnet dotnet deleted a comment from MauiBot May 21, 2026
@kubaflo

kubaflo commented May 21, 2026

Copy link
Copy Markdown
Contributor

/review -b feature/regression-check -p ios

@sheiksyedm sheiksyedm marked this pull request as ready for review May 21, 2026 11:23
@kubaflo

kubaflo commented May 22, 2026

Copy link
Copy Markdown
Contributor

/review -b feature/refactor-copilot-yml

@MauiBot MauiBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expert Review — 1 findings

See inline comments for details.

// On iOS/MacCatalyst 26+, the tab bar renders as a floating glass overlay.
// Extend behind it when inside a visible UITabBarController so content
// isn't clipped at the old tab bar boundary.
if ((OperatingSystem.IsIOSVersionAtLeast(26) || OperatingSystem.IsMacCatalystVersionAtLeast(26))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[major] iOS/MacCatalyst Platform Specifics — This extends the bottom edge for every visible UITabBarController on iOS/MacCatalyst 26+, regardless of the MAUI TabbedPage translucency setting. Concrete scenario: an app sets TabbedPage.On<iOS>().SetTranslucencyMode(TranslucencyMode.Opaque) to keep content above an opaque tab bar; this branch still opts the navigation child into bottom extension whenever the tab bar is visible. Please scope this to the default/floating-glass case or respect TabBar.Translucent/the MAUI translucency mode so explicit opaque tab bars keep their existing layout behavior.

@MauiBot MauiBot added the s/agent-fix-win AI found a better alternative fix than the PR label May 22, 2026

@kubaflo kubaflo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please check the ai's suggestions?

@kubaflo

kubaflo commented May 24, 2026

Copy link
Copy Markdown
Contributor

/review -b feature/refactor-copilot-yml

MauiBot

This comment was marked as outdated.

@SyedAbdulAzeemSF4852

Copy link
Copy Markdown
Contributor Author

Could you please check the ai's suggestions?

@kubaflo , Reviewed the AI suggestions and incorporated the valid ones.

@sheiksyedm

Copy link
Copy Markdown
Contributor

/azp run maui-pr-uitests , maui-pr-devicetests

@kubaflo

kubaflo commented May 29, 2026

Copy link
Copy Markdown
Contributor

/review -b feature/refactor-copilot-yml -p ios

@kubaflo kubaflo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you check the ai's suggestions?

@dotnet dotnet deleted a comment from MauiBot May 30, 2026
@kubaflo

kubaflo commented May 30, 2026

Copy link
Copy Markdown
Contributor

/review -b feature/refactor-copilot-yml -p ios

@MauiBot

This comment has been minimized.

@kubaflo

kubaflo commented May 31, 2026

Copy link
Copy Markdown
Contributor

/review -b feature/enhanced-reviewer

MauiBot

This comment was marked as outdated.

@kubaflo

kubaflo commented May 31, 2026

Copy link
Copy Markdown
Contributor

/review -b feature/enhanced-reviewer

@beeradmoore

Copy link
Copy Markdown
Contributor

We tested this on our app experiencing the same issue. We have a CollectionView under it not just a page like the demo above. The Grid and the ContentPage both needed SafeAreaEdges=None. This now allows content to scroll all the way to the bottom of the page as intended and not be blocked by a big white block. However there is an issue where the bottom item of the CollectionView still sits at the bottom of the screen and is hidden under the tab bar.

Our workaround for that is to add a footer in the CollectionView to the same height as SafeAreaInsets.Bottom. I feel like if I created a native iOS app with a tab bar and a UICollectionView that it would just handled it. But I have not done that much native since pre-Xamarin.Forms days.

@kubaflo

kubaflo commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

/review -b feature/enhanced-reviewer -b ios

@kubaflo

kubaflo commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

/review -b feature/enhanced-reviewer

@MauiBot MauiBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI Review Summary

@SyedAbdulAzeemSF4852 — new AI review results are available based on this last commit: 07d44e3.
refresh iOS and Mac screenshot baselines To request a fresh review after new comments or commits, comment /review rerun.

Gate Failed Code Review In Review Confidence Medium Platform Android

Review Sessions — click to expand
Gate — Test Before & After Fix

Gate Result: ❌ FAILED

Platform: ANDROID · Base: main · Merge base: e904e900

🩺 Test filter mismatch — filter Issue35490 matched 0 tests. The test runner produced zero results because no test class or method matched the filter. Common causes: the gate filter was derived from the file name but the actual test class is named differently, or the test was renamed/moved without updating the auto-detection. Verify the test class name matches what the gate is searching for.

Test Without Fix (expect FAIL) With Fix (expect PASS)
🖥️ Issue35490 Issue35490 🔍 NO MATCH 🔍 NO MATCH
🔴 Without fix — 🖥️ Issue35490: 🔍 NO MATCH · 722s
  Determining projects to restore...
  Restored /home/vsts/work/1/s/src/Graphics/src/Graphics/Graphics.csproj (in 563 ms).
  Restored /home/vsts/work/1/s/src/Essentials/src/Essentials.csproj (in 4.01 sec).
  Restored /home/vsts/work/1/s/src/Core/src/Core.csproj (in 5.47 sec).
  Restored /home/vsts/work/1/s/src/Core/maps/src/Maps.csproj (in 2.02 sec).
  Restored /home/vsts/work/1/s/src/Controls/src/Xaml/Controls.Xaml.csproj (in 35 ms).
  Restored /home/vsts/work/1/s/src/Controls/src/Core/Controls.Core.csproj (in 19 ms).
  Restored /home/vsts/work/1/s/src/Controls/Maps/src/Controls.Maps.csproj (in 36 ms).
  Restored /home/vsts/work/1/s/src/Controls/Foldable/src/Controls.Foldable.csproj (in 287 ms).
  Restored /home/vsts/work/1/s/src/BlazorWebView/src/Maui/Microsoft.AspNetCore.Components.WebView.Maui.csproj (in 1.02 sec).
  Restored /home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj (in 2.17 sec).
  1 of 11 projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Graphics -> /home/vsts/work/1/s/artifacts/bin/Graphics/Debug/net10.0-android36.0/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Essentials -> /home/vsts/work/1/s/artifacts/bin/Essentials/Debug/net10.0-android36.0/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Core -> /home/vsts/work/1/s/artifacts/bin/Core/Debug/net10.0-android36.0/Microsoft.Maui.dll
  Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Maps -> /home/vsts/work/1/s/artifacts/bin/Maps/Debug/net10.0-android36.0/Microsoft.Maui.Maps.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.Core/Debug/net10.0-android36.0/Microsoft.Maui.Controls.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Controls.Xaml -> /home/vsts/work/1/s/artifacts/bin/Controls.Xaml/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Xaml.dll
  Microsoft.AspNetCore.Components.WebView.Maui -> /home/vsts/work/1/s/artifacts/bin/Microsoft.AspNetCore.Components.WebView.Maui/Debug/net10.0-android36.0/Microsoft.AspNetCore.Components.WebView.Maui.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Controls.Foldable -> /home/vsts/work/1/s/artifacts/bin/Controls.Foldable/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Foldable.dll
  Controls.Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.Maps/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Maps.dll
  Controls.TestCases.HostApp -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Controls.TestCases.HostApp.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Graphics -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Essentials -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Core -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.dll
  Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Maps.dll
  Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Controls.Foldable -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Foldable.dll
  Controls.Xaml -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Xaml.dll
  Microsoft.AspNetCore.Components.WebView.Maui -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.AspNetCore.Components.WebView.Maui.dll
  Controls.Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Maps.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:09:09.56
Broadcasting: Intent { act=android.intent.action.CLOSE_SYSTEM_DIALOGS flg=0x400000 }
Broadcast completed: result=0
  Determining projects to restore...
  Restored /home/vsts/work/1/s/src/TestUtils/src/VisualTestUtils/VisualTestUtils.csproj (in 1.02 sec).
  Restored /home/vsts/work/1/s/src/TestUtils/src/UITest.NUnit/UITest.NUnit.csproj (in 1.07 sec).
  Restored /home/vsts/work/1/s/src/TestUtils/src/UITest.Core/UITest.Core.csproj (in 3 ms).
  Restored /home/vsts/work/1/s/src/TestUtils/src/VisualTestUtils.MagickNet/VisualTestUtils.MagickNet.csproj (in 11.23 sec).
  Restored /home/vsts/work/1/s/src/Controls/tests/CustomAttributes/Controls.CustomAttributes.csproj (in 6 ms).
  Restored /home/vsts/work/1/s/src/TestUtils/src/UITest.Appium/UITest.Appium.csproj (in 13 ms).
  Restored /home/vsts/work/1/s/src/Controls/tests/TestCases.Android.Tests/Controls.TestCases.Android.Tests.csproj (in 9.07 sec).
  Restored /home/vsts/work/1/s/src/TestUtils/src/UITest.Analyzers/UITest.Analyzers.csproj (in 2.81 sec).
  5 of 13 projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Graphics -> /home/vsts/work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Essentials -> /home/vsts/work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
  Controls.CustomAttributes -> /home/vsts/work/1/s/artifacts/bin/Controls.CustomAttributes/Debug/net10.0/Controls.CustomAttributes.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Core -> /home/vsts/work/1/s/artifacts/bin/Core/Debug/net10.0/Microsoft.Maui.dll
  Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
  VisualTestUtils -> /home/vsts/work/1/s/artifacts/bin/VisualTestUtils/Debug/netstandard2.0/VisualTestUtils.dll
  UITest.Core -> /home/vsts/work/1/s/artifacts/bin/UITest.Core/Debug/net10.0/UITest.Core.dll
  UITest.NUnit -> /home/vsts/work/1/s/artifacts/bin/UITest.NUnit/Debug/net10.0/UITest.NUnit.dll
  UITest.Appium -> /home/vsts/work/1/s/artifacts/bin/UITest.Appium/Debug/net10.0/UITest.Appium.dll
  VisualTestUtils.MagickNet -> /home/vsts/work/1/s/artifacts/bin/VisualTestUtils.MagickNet/Debug/netstandard2.0/VisualTestUtils.MagickNet.dll
  UITest.Analyzers -> /home/vsts/work/1/s/artifacts/bin/UITest.Analyzers/Debug/netstandard2.0/UITest.Analyzers.dll
  Controls.TestCases.Android.Tests -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll
Test run for /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (x64)

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.20]   Discovering: Controls.TestCases.Android.Tests
[xUnit.net 00:00:00.86]   Discovered:  Controls.TestCases.Android.Tests
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll
   NUnit3TestExecutor discovered 0 of 0 NUnit test cases using Current Discovery mode, Explicit run
NUnit Adapter 4.5.0.0: Test execution complete
No test matches the given testcase filter `Issue35490` in /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll
Results File: /home/vsts/work/1/s/CustomAgentLogsTmp/UITests/TestResults/Issue35490.trx

>>> TRX_RESULT_FILE: /home/vsts/work/1/s/CustomAgentLogsTmp/UITests/TestResults/Issue35490.trx

🟢 With fix — 🖥️ Issue35490: 🔍 NO MATCH · 1981s

(truncated to last 15,000 chars)

ugging.targets(333,5): error ADB0010:    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/36.1.2/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010:    at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/36.1.2/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010: --- End of stack trace from previous location --- [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/36.1.2/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010:    at AndroidDeviceExtensions.PushAndInstallPackageAsync(AndroidDevice device, PushAndInstallCommand command, CancellationToken token) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/36.1.2/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010:    at AndroidDeviceExtensions.PushAndInstallPackageAsync(AndroidDevice device, PushAndInstallCommand command, CancellationToken token) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/36.1.2/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010:    at Xamarin.Android.Tasks.FastDeploy.InstallPackage(Boolean installed) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/36.1.2/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010:    at Xamarin.Android.Tasks.FastDeploy.InstallPackage(Boolean installed) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/36.1.2/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010:    at Xamarin.Android.Tasks.FastDeploy.RunInstall() [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-android]

Build FAILED.

/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/36.1.2/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010: Mono.AndroidTools.InstallFailedException: Unexpected install output: cmd: Failure calling service package: Broken pipe (32) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/36.1.2/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010:  [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/36.1.2/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010:    at Mono.AndroidTools.Internal.AdbOutputParsing.CheckInstallSuccess(String output, String packageName) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/36.1.2/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010:    at Mono.AndroidTools.AndroidDevice.<>c__DisplayClass105_0.<InstallPackage>b__0(Task`1 t) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/36.1.2/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010:    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/36.1.2/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010: --- End of stack trace from previous location --- [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/36.1.2/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010:    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/36.1.2/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010:    at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/36.1.2/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010: --- End of stack trace from previous location --- [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/36.1.2/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010:    at AndroidDeviceExtensions.PushAndInstallPackageAsync(AndroidDevice device, PushAndInstallCommand command, CancellationToken token) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/36.1.2/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010:    at AndroidDeviceExtensions.PushAndInstallPackageAsync(AndroidDevice device, PushAndInstallCommand command, CancellationToken token) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/36.1.2/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010:    at Xamarin.Android.Tasks.FastDeploy.InstallPackage(Boolean installed) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/36.1.2/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010:    at Xamarin.Android.Tasks.FastDeploy.InstallPackage(Boolean installed) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/36.1.2/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010:    at Xamarin.Android.Tasks.FastDeploy.RunInstall() [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-android]
    0 Warning(s)
    1 Error(s)

Time Elapsed 00:13:39.03
* daemon not running; starting now at tcp:5037
* daemon started successfully
  Determining projects to restore...
  All projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Graphics -> /home/vsts/work/1/s/artifacts/bin/Graphics/Debug/net10.0-android36.0/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Essentials -> /home/vsts/work/1/s/artifacts/bin/Essentials/Debug/net10.0-android36.0/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Core -> /home/vsts/work/1/s/artifacts/bin/Core/Debug/net10.0-android36.0/Microsoft.Maui.dll
  Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Maps -> /home/vsts/work/1/s/artifacts/bin/Maps/Debug/net10.0-android36.0/Microsoft.Maui.Maps.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.Core/Debug/net10.0-android36.0/Microsoft.Maui.Controls.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Controls.Foldable -> /home/vsts/work/1/s/artifacts/bin/Controls.Foldable/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Foldable.dll
  Microsoft.AspNetCore.Components.WebView.Maui -> /home/vsts/work/1/s/artifacts/bin/Microsoft.AspNetCore.Components.WebView.Maui/Debug/net10.0-android36.0/Microsoft.AspNetCore.Components.WebView.Maui.dll
  Controls.Xaml -> /home/vsts/work/1/s/artifacts/bin/Controls.Xaml/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Xaml.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Controls.Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.Maps/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Maps.dll
  Controls.TestCases.HostApp -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Controls.TestCases.HostApp.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Graphics -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Essentials -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Core -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.dll
  Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Maps.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Microsoft.AspNetCore.Components.WebView.Maui -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.AspNetCore.Components.WebView.Maui.dll
  Controls.Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Maps.dll
  Controls.Xaml -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Xaml.dll
  Controls.Foldable -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Foldable.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:08:41.20
Broadcasting: Intent { act=android.intent.action.CLOSE_SYSTEM_DIALOGS flg=0x400000 }
Broadcast completed: result=0
  Determining projects to restore...
  All projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Graphics -> /home/vsts/work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
  Controls.CustomAttributes -> /home/vsts/work/1/s/artifacts/bin/Controls.CustomAttributes/Debug/net10.0/Controls.CustomAttributes.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Essentials -> /home/vsts/work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Core -> /home/vsts/work/1/s/artifacts/bin/Core/Debug/net10.0/Microsoft.Maui.dll
  Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.80-ci+azdo.14285925
  Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
  UITest.Core -> /home/vsts/work/1/s/artifacts/bin/UITest.Core/Debug/net10.0/UITest.Core.dll
  VisualTestUtils -> /home/vsts/work/1/s/artifacts/bin/VisualTestUtils/Debug/netstandard2.0/VisualTestUtils.dll
  UITest.NUnit -> /home/vsts/work/1/s/artifacts/bin/UITest.NUnit/Debug/net10.0/UITest.NUnit.dll
  VisualTestUtils.MagickNet -> /home/vsts/work/1/s/artifacts/bin/VisualTestUtils.MagickNet/Debug/netstandard2.0/VisualTestUtils.MagickNet.dll
  UITest.Appium -> /home/vsts/work/1/s/artifacts/bin/UITest.Appium/Debug/net10.0/UITest.Appium.dll
  UITest.Analyzers -> /home/vsts/work/1/s/artifacts/bin/UITest.Analyzers/Debug/netstandard2.0/UITest.Analyzers.dll
  Controls.TestCases.Android.Tests -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll
Test run for /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (x64)

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.14]   Discovering: Controls.TestCases.Android.Tests
[xUnit.net 00:00:00.47]   Discovered:  Controls.TestCases.Android.Tests
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll
   NUnit3TestExecutor discovered 0 of 0 NUnit test cases using Current Discovery mode, Explicit run
NUnit Adapter 4.5.0.0: Test execution complete
No test matches the given testcase filter `Issue35490` in /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll
Results File: /home/vsts/work/1/s/CustomAgentLogsTmp/UITests/TestResults/Issue35490.trx

>>> TRX_RESULT_FILE: /home/vsts/work/1/s/CustomAgentLogsTmp/UITests/TestResults/Issue35490.trx

⚠️ Failure Details

  • 🔍 Issue35490 without fix: test filter matched 0 tests
    • filter: Issue35490
  • 🔍 Issue35490 with fix: test filter matched 0 tests
    • filter: Issue35490
📁 Fix files reverted (2 files)
  • eng/pipelines/ci-copilot.yml
  • src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs

UI Tests — TabbedPage

Detected UI test categories: TabbedPage

Deep UI tests — 74 passed, 0 failed across 1 category on platform-pool agent (replaces in-process counts above).

🧪 UI Test Execution Results (deep, platform pool)

Category Tests Snapshot diffs
TabbedPage 74/74 ✓
📎 Download drop-deep-uitests artifact (TRX + snapshot diffs)

Pre-Flight — Context & Validation

Issue: #35490 - IOS Glass UI - TabbedPage with a Navigation Page - page cuts off above native floating tab bar
PR: #35523 - [iOS/Mac Catalyst 26] Fix NavigationPage content not extending behind floating glass tab bar
Platforms Affected: iOS, MacCatalyst (requested testing platform: android; no Android implementation/test surface)
Files Changed: 1 implementation, 5 test/snapshot

Key Findings

  • The issue is specific to NavigationPage children inside TabbedPage on iOS/MacCatalyst 26+, where the floating glass tab bar overlays content but the child navigation controller still lays out as if the old solid tab bar consumes bottom space.
  • PR fix changes ParentingViewController.ViewWillAppear in NavigationRenderer.cs to OR UIRectEdge.Bottom into EdgesForExtendedLayout on iOS/MacCatalyst 26+ when a visible translucent UITabBarController is present.
  • Test coverage is an iOS/MacCatalyst screenshot UI test (UITestCategories.TabbedPage) plus platform baselines; it is compiled out for Android.
  • PR discussion notes one user confirmed the reproduction project is fixed but their main app still had an unresolved case; author notes Android gate failure is unrelated because this PR/test are iOS/Mac-only.

Code Review Summary

Verdict: LGTM
Confidence: medium
Errors: 0 | Warnings: 0 | Suggestions: 0

Key code review findings:

  • No ❌ Error, ⚠️ Warning, or 💡 Suggestion findings.
  • Failure-mode probe: custom/opaque tab bars are guarded by tbc.TabBar.Translucent, so explicit opaque behavior is preserved.
  • Blast radius: affects NavigationPage child controllers hosted under a visible translucent UITabBarController on iOS/MacCatalyst 26+; Android/Windows are unaffected.

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #35523 In ParentingViewController.ViewWillAppear, preserve nav-bar translucency logic and add bottom extended layout for visible translucent iOS/MacCatalyst 26 tab bars. ❌ FAILED (Gate result supplied by caller; do not re-run) src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs, UI test/snapshots Original PR; gate failure appears Android/platform mismatch rather than affected iOS test surface.

Code Review — Deep Analysis

Code Review — PR #35523

Independent Assessment

What this changes: NavigationPage child controllers on iOS/MacCatalyst 26+ now extend their bottom edge behind a visible translucent UITabBarController tab bar, while preserving existing navigation-bar translucency behavior. Adds UI screenshot coverage for the TabbedPage/NavigationPage case.
Inferred motivation: iOS 26 floating glass tab bars overlay content differently, causing NavigationPage children in TabbedPage to stop above the old tab bar boundary and leave a visual gap.

Reconciliation with PR Narrative

Author claims: Fixes iOS/MacCatalyst 26 floating glass tab bar clipping for NavigationPage children inside TabbedPage, with iOS/Mac validation and snapshots.
Agreement/disagreement: Matches the code. Earlier review comments about missing Mac baseline, stale iOS-26 baseline, and ignoring opaque tab bars appear addressed: Mac baseline exists, iOS/iOS-26 baselines exist, and the code now requires tbc.TabBar.Translucent.

Findings

No ❌ Error, ⚠️ Warning, or 💡 Suggestion findings.

Devil's Advocate

The main risk is UIKit default translucency behavior changing or a custom tab bar still being translucent while app authors expect non-extended layout. The added TabBar.Translucent guard makes this acceptable and respects explicit opaque mode. I could not empirically run iOS/Mac UI tests in this Linux environment, but CI check suites report success.

Verdict: LGTM

Confidence: medium
Summary: The implementation is narrow, platform-version guarded, and consistent with existing TabbedRenderer translucency behavior. CI check runs/suites for the head SHA report success; no actionable code issues found.


Fix — Analysis & Comparison

Fix Candidates

# Source Approach Test Result Files Changed Notes
1 maui-expert-reviewer TabbedRenderer-owned child bottom-extension: mutate child EdgesForExtendedLayout from the tab container. ⚠️ Blocked (Android not applicable) 2 files Not better: risks clearing unrelated child bottom-edge state.
2 maui-expert-reviewer Selected child frame extension in TabbedRenderer.ViewDidLayoutSubviews. ⚠️ Blocked (Android not applicable) 2 files Not better: risks UIKit/MAUI layout desynchronization.
3 maui-expert-reviewer Selected child safe-area compensation using renderer-owned AdditionalSafeAreaInsets delta. ⚠️ Blocked (Android not applicable) 2 files Not better: more complex, allocates in layout hot path, relies on negative safe-area semantics.
PR PR #35523 NavigationRenderer.ParentingViewController.ViewWillAppear ORs UIRectEdge.Bottom for visible translucent iOS/MacCatalyst 26 tab bars. ❌ FAILED (supplied gate result; not re-run) 1 implementation file + UI test/snapshots Narrowest approach; Android gate result is not applicable to the iOS/Mac-only regression.

Cross-Pollination

Model/Reviewer Round New Ideas? Details
maui-expert-reviewer 1 Yes Proposed moving policy to TabbedRenderer and mutating child controller bottom edges.
maui-expert-reviewer 2 Yes After candidate 1 risk, proposed selected child frame extension instead of global edge mutation.
maui-expert-reviewer 3 Yes After candidate 2 risk, proposed selected child safe-area compensation instead of frame mutation.
orchestrator synthesis 4 No Remaining variations collapse into the same three root strategies: controller edge policy, container frame mutation, or safe-area compensation. Trivial variations would not address the Android validation blocker or improve robustness.

Exhausted: Yes
Selected Fix: PR #35523 — The alternatives were not testable on Android and each introduced more risk/complexity than the PR's narrow nested-controller edge-extension fix. No candidate passed all tests or was demonstrably better.


Per-candidate narrative

try-fix-1

Approach

TabbedRenderer-owned child bottom-extension. Move the iOS/MacCatalyst 26 floating-tab-bar policy into TabbedRenderer, updating child controller EdgesForExtendedLayout after controller creation, selection changes, and tab-bar translucency changes.

Diff

diff --git a/src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs b/src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs
index 34101206ca..78cd76d723 100644
--- a/src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs
+++ b/src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs
@@ -1538,17 +1538,6 @@ namespace Microsoft.Maui.Controls.Handlers.Compatibility
 
 				var edges = isTranslucent ? UIRectEdge.All : UIRectEdge.None;
 
-				// On iOS/MacCatalyst 26+, the tab bar renders as a floating glass overlay.
-				// Extend behind it when inside a visible UITabBarController so content
-				// isn't clipped at the old tab bar boundary.
-				if ((OperatingSystem.IsIOSVersionAtLeast(26) || OperatingSystem.IsMacCatalystVersionAtLeast(26))
-					&& TabBarController is { } tbc
-					&& !tbc.TabBar.Hidden
-					&& tbc.TabBar.Translucent)
-				{
-					edges |= UIRectEdge.Bottom;
-				}
-
 				EdgesForExtendedLayout = edges;
 
 				base.ViewWillAppear(animated);
diff --git a/src/Controls/src/Core/Compatibility/Handlers/TabbedPage/iOS/TabbedRenderer.cs b/src/Controls/src/Core/Compatibility/Handlers/TabbedPage/iOS/TabbedRenderer.cs
index 3ab57244b6..f0c3af9460 100644
--- a/src/Controls/src/Core/Compatibility/Handlers/TabbedPage/iOS/TabbedRenderer.cs
+++ b/src/Controls/src/Core/Compatibility/Handlers/TabbedPage/iOS/TabbedRenderer.cs
@@ -51,6 +51,8 @@ namespace Microsoft.Maui.Controls.Handlers.Compatibility
 			set
 			{
 				base.SelectedViewController = value;
+				UpdateFloatingTabBarChildLayout();
+
 				// If the selected view controller is the "More" navigation controller, do not update the current page
 				// because it is a special case where the user is navigating to a different set of tabs
 				if (value == MoreNavigationController)
@@ -218,6 +220,7 @@ namespace Microsoft.Maui.Controls.Handlers.Compatibility
 			e.Apply((o, i, c) => SetupPage((Page)o, i), (o, i) => TeardownPage((Page)o, i), Reset);
 
 			SetControllers();
+			UpdateFloatingTabBarChildLayout();
 
 			UIViewController controller = null;
 			if (Tabbed?.CurrentPage is Page currentPage)
@@ -490,16 +493,45 @@ namespace Microsoft.Maui.Controls.Handlers.Compatibility
 			{
 				case TranslucencyMode.Translucent:
 					TabBar.Translucent = true;
+					UpdateFloatingTabBarChildLayout();
 					return;
 				case TranslucencyMode.Opaque:
 					TabBar.Translucent = false;
+					UpdateFloatingTabBarChildLayout();
 					return;
 				default:
 					TabBar.Translucent = _defaultBarTranslucent.GetValueOrDefault();
+					UpdateFloatingTabBarChildLayout();
 					return;
 			}
 		}
 
+		bool ShouldExtendChildrenUnderFloatingTabBar()
+		{
+			return (OperatingSystem.IsIOSVersionAtLeast(26) || OperatingSystem.IsMacCatalystVersionAtLeast(26))
+				&& TabBar is not null
+				&& !TabBar.Hidden
+				&& TabBar.Translucent;
+		}
+
+		void UpdateFloatingTabBarChildLayout()
+		{
+			if (ViewControllers is not { } viewControllers)
+				return;
+
+			var shouldExtend = ShouldExtendChildrenUnderFloatingTabBar();
+			foreach (var controller in viewControllers)
+			{
+				if (controller is null)
+					continue;
+
+				if (shouldExtend)
+					controller.EdgesForExtendedLayout |= UIRectEdge.Bottom;
+				else
+					controller.EdgesForExtendedLayout &= ~UIRectEdge.Bottom;
+			}
+		}
+
 		void UpdateTabBarItems()
 		{
 			foreach (var page in Tabbed.InternalChildren)

Test Results

Result: Blocked

Android validation was not executed because PR #35523 and NavigationPageChildContentExtendsUnderFloatingTabBar are iOS/MacCatalyst-only (#if IOS || MACCATALYST). Android cannot validate iOS 26 floating glass tab bar behavior.

Failure Analysis

The candidate is not demonstrably better than the PR fix. Self-review found a major correctness risk: clearing UIRectEdge.Bottom from all tab children when the tab bar is opaque/hidden can remove unrelated bottom-extension state. This informs the next candidate: avoid global child state mutation or track original/owned state precisely.


try-fix-2

Approach

Selected child frame extension. Adjust only the currently selected tab child view's native frame in TabbedRenderer.ViewDidLayoutSubviews when running under a visible translucent iOS/MacCatalyst 26 tab bar.

Diff

diff --git a/src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs b/src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs
index 34101206ca..78cd76d723 100644
--- a/src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs
+++ b/src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs
@@ -1538,17 +1538,6 @@ namespace Microsoft.Maui.Controls.Handlers.Compatibility
 
 				var edges = isTranslucent ? UIRectEdge.All : UIRectEdge.None;
 
-				// On iOS/MacCatalyst 26+, the tab bar renders as a floating glass overlay.
-				// Extend behind it when inside a visible UITabBarController so content
-				// isn't clipped at the old tab bar boundary.
-				if ((OperatingSystem.IsIOSVersionAtLeast(26) || OperatingSystem.IsMacCatalystVersionAtLeast(26))
-					&& TabBarController is { } tbc
-					&& !tbc.TabBar.Hidden
-					&& tbc.TabBar.Translucent)
-				{
-					edges |= UIRectEdge.Bottom;
-				}
-
 				EdgesForExtendedLayout = edges;
 
 				base.ViewWillAppear(animated);
diff --git a/src/Controls/src/Core/Compatibility/Handlers/TabbedPage/iOS/TabbedRenderer.cs b/src/Controls/src/Core/Compatibility/Handlers/TabbedPage/iOS/TabbedRenderer.cs
index 3ab57244b6..f2ce0f81e7 100644
--- a/src/Controls/src/Core/Compatibility/Handlers/TabbedPage/iOS/TabbedRenderer.cs
+++ b/src/Controls/src/Core/Compatibility/Handlers/TabbedPage/iOS/TabbedRenderer.cs
@@ -51,6 +51,7 @@ namespace Microsoft.Maui.Controls.Handlers.Compatibility
 			set
 			{
 				base.SelectedViewController = value;
+
 				// If the selected view controller is the "More" navigation controller, do not update the current page
 				// because it is a special case where the user is navigating to a different set of tabs
 				if (value == MoreNavigationController)
@@ -137,6 +138,8 @@ namespace Microsoft.Maui.Controls.Handlers.Compatibility
 			// in narrow viewports (< 667 points) before Element is set. Guard against this.
 			if (Element is IView view)
 				view.Arrange(View.Bounds.ToRectangle());
+
+			ExtendSelectedChildFrameUnderFloatingTabBar();
 		}
 
 		protected override void Dispose(bool disposing)
@@ -216,7 +219,7 @@ namespace Microsoft.Maui.Controls.Handlers.Compatibility
 		void OnPagesChanged(object sender, NotifyCollectionChangedEventArgs e)
 		{
 			e.Apply((o, i, c) => SetupPage((Page)o, i), (o, i) => TeardownPage((Page)o, i), Reset);
-
+			SetControllers();
 			SetControllers();
 
 			UIViewController controller = null;
@@ -490,16 +493,46 @@ namespace Microsoft.Maui.Controls.Handlers.Compatibility
 			{
 				case TranslucencyMode.Translucent:
 					TabBar.Translucent = true;
+					View.SetNeedsLayout();
 					return;
 				case TranslucencyMode.Opaque:
 					TabBar.Translucent = false;
+					View.SetNeedsLayout();
 					return;
 				default:
 					TabBar.Translucent = _defaultBarTranslucent.GetValueOrDefault();
+					View.SetNeedsLayout();
 					return;
 			}
 		}
 
+		bool ShouldExtendSelectedChildFrameUnderFloatingTabBar()
+		{
+			return (OperatingSystem.IsIOSVersionAtLeast(26) || OperatingSystem.IsMacCatalystVersionAtLeast(26))
+				&& TabBar is not null
+				&& !TabBar.Hidden
+				&& TabBar.Translucent;
+		}
+
+		void ExtendSelectedChildFrameUnderFloatingTabBar()
+		{
+			if (!ShouldExtendSelectedChildFrameUnderFloatingTabBar())
+				return;
+
+			var controller = SelectedViewController;
+			if (controller is null || controller == MoreNavigationController || controller.View is null || View is null)
+				return;
+
+			var frame = controller.View.Frame;
+			var desiredBottom = View.Bounds.Bottom;
+			if (frame.Bottom >= desiredBottom)
+				return;
+
+			frame.Height += desiredBottom - frame.Bottom;
+			controller.View.Frame = frame;
+			controller.View.SetNeedsLayout();
+		}
+
 		void UpdateTabBarItems()
 		{
 			foreach (var page in Tabbed.InternalChildren)

Test Results

Result: Blocked

Android validation was not executed because PR #35523 and NavigationPageChildContentExtendsUnderFloatingTabBar are iOS/MacCatalyst-only (#if IOS || MACCATALYST). Android cannot validate iOS 26 floating glass tab bar behavior.

Failure Analysis

The candidate is not demonstrably better than the PR fix. Self-review found a major layout risk: mutating native child frames after UIKit and MAUI layout can desynchronize container layout, hit-testing, and future UIKit layout passes. The next candidate should avoid direct frame mutation and avoid global child state changes.


try-fix-3

Approach

Selected child safe-area compensation. Compensate the selected tab child controller's bottom safe area while a visible translucent iOS/MacCatalyst 26 tab bar is present, storing/restoring only the renderer-owned delta.

Diff

diff --git a/src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs b/src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs
index 34101206ca..78cd76d723 100644
--- a/src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs
+++ b/src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs
@@ -1538,17 +1538,6 @@ namespace Microsoft.Maui.Controls.Handlers.Compatibility
 
 				var edges = isTranslucent ? UIRectEdge.All : UIRectEdge.None;
 
-				// On iOS/MacCatalyst 26+, the tab bar renders as a floating glass overlay.
-				// Extend behind it when inside a visible UITabBarController so content
-				// isn't clipped at the old tab bar boundary.
-				if ((OperatingSystem.IsIOSVersionAtLeast(26) || OperatingSystem.IsMacCatalystVersionAtLeast(26))
-					&& TabBarController is { } tbc
-					&& !tbc.TabBar.Hidden
-					&& tbc.TabBar.Translucent)
-				{
-					edges |= UIRectEdge.Bottom;
-				}
-
 				EdgesForExtendedLayout = edges;
 
 				base.ViewWillAppear(animated);
diff --git a/src/Controls/src/Core/Compatibility/Handlers/TabbedPage/iOS/TabbedRenderer.cs b/src/Controls/src/Core/Compatibility/Handlers/TabbedPage/iOS/TabbedRenderer.cs
index 3ab57244b6..71e042e996 100644
--- a/src/Controls/src/Core/Compatibility/Handlers/TabbedPage/iOS/TabbedRenderer.cs
+++ b/src/Controls/src/Core/Compatibility/Handlers/TabbedPage/iOS/TabbedRenderer.cs
@@ -28,6 +28,7 @@ namespace Microsoft.Maui.Controls.Handlers.Compatibility
 		IMauiContext _mauiContext;
 		UITabBarAppearance _tabBarAppearance;
 		WeakReference<VisualElement> _element;
+		readonly Dictionary<UIViewController, nfloat> _floatingTabBarSafeAreaAdjustments = new();
 
 		Brush _currentBarBackground;
 
@@ -51,6 +52,8 @@ namespace Microsoft.Maui.Controls.Handlers.Compatibility
 			set
 			{
 				base.SelectedViewController = value;
+				UpdateSelectedChildFloatingTabBarSafeArea();
+
 				// If the selected view controller is the "More" navigation controller, do not update the current page
 				// because it is a special case where the user is navigating to a different set of tabs
 				if (value == MoreNavigationController)
@@ -137,12 +140,18 @@ namespace Microsoft.Maui.Controls.Handlers.Compatibility
 			// in narrow viewports (< 667 points) before Element is set. Guard against this.
 			if (Element is IView view)
 				view.Arrange(View.Bounds.ToRectangle());
+
+			UpdateSelectedChildFloatingTabBarSafeArea();
 		}
 
 		protected override void Dispose(bool disposing)
 		{
 			if (disposing)
 			{
+				var adjustedControllers = new List<UIViewController>(_floatingTabBarSafeAreaAdjustments.Keys);
+				foreach (var controller in adjustedControllers)
+					RestoreFloatingTabBarSafeArea(controller);
+
 				_tabBarAppearance?.Dispose();
 				_tabBarAppearance = null;
 
@@ -216,7 +225,7 @@ namespace Microsoft.Maui.Controls.Handlers.Compatibility
 		void OnPagesChanged(object sender, NotifyCollectionChangedEventArgs e)
 		{
 			e.Apply((o, i, c) => SetupPage((Page)o, i), (o, i) => TeardownPage((Page)o, i), Reset);
-
+			SetControllers();
 			SetControllers();
 
 			UIViewController controller = null;
@@ -490,14 +499,73 @@ namespace Microsoft.Maui.Controls.Handlers.Compatibility
 			{
 				case TranslucencyMode.Translucent:
 					TabBar.Translucent = true;
-					return;
+					break;
 				case TranslucencyMode.Opaque:
 					TabBar.Translucent = false;
-					return;
+					break;
 				default:
 					TabBar.Translucent = _defaultBarTranslucent.GetValueOrDefault();
-					return;
+					break;
+			}
+
+			View.SetNeedsLayout();
+			UpdateSelectedChildFloatingTabBarSafeArea();
+		}
+
+		bool ShouldCompensateForFloatingTabBar()
+		{
+			return (OperatingSystem.IsIOSVersionAtLeast(26) || OperatingSystem.IsMacCatalystVersionAtLeast(26))
+				&& TabBar is not null
+				&& !TabBar.Hidden
+				&& TabBar.Translucent;
+		}
+
+		void UpdateSelectedChildFloatingTabBarSafeArea()
+		{
+			var selected = SelectedViewController;
+			var adjustedControllers = new List<UIViewController>(_floatingTabBarSafeAreaAdjustments.Keys);
+			foreach (var controller in adjustedControllers)
+			{
+				if (controller != selected)
+					RestoreFloatingTabBarSafeArea(controller);
 			}
+
+			if (!ShouldCompensateForFloatingTabBar() || selected is null || selected == MoreNavigationController)
+			{
+				if (selected is not null)
+					RestoreFloatingTabBarSafeArea(selected);
+
+				return;
+			}
+
+			var tabBarHeight = TabBar.Frame.Height;
+			if (tabBarHeight <= 0)
+				return;
+
+			ApplyFloatingTabBarSafeArea(selected, tabBarHeight);
+		}
+
+		void ApplyFloatingTabBarSafeArea(UIViewController controller, nfloat tabBarHeight)
+		{
+			var currentInsets = controller.AdditionalSafeAreaInsets;
+			if (_floatingTabBarSafeAreaAdjustments.TryGetValue(controller, out var previousAdjustment))
+				currentInsets.Bottom += previousAdjustment;
+
+			currentInsets.Bottom -= tabBarHeight;
+			controller.AdditionalSafeAreaInsets = currentInsets;
+			_floatingTabBarSafeAreaAdjustments[controller] = tabBarHeight;
+			controller.View?.SetNeedsLayout();
+		}
+
+		void RestoreFloatingTabBarSafeArea(UIViewController controller)
+		{
+			if (!_floatingTabBarSafeAreaAdjustments.Remove(controller, out var previousAdjustment))
+				return;
+
+			var insets = controller.AdditionalSafeAreaInsets;
+			insets.Bottom += previousAdjustment;
+			controller.AdditionalSafeAreaInsets = insets;
+			controller.View?.SetNeedsLayout();
 		}
 
 		void UpdateTabBarItems()

Test Results

Result: Blocked

Android validation was not executed because PR #35523 and NavigationPageChildContentExtendsUnderFloatingTabBar are iOS/MacCatalyst-only (#if IOS || MACCATALYST). Android cannot validate iOS 26 floating glass tab bar behavior.

Failure Analysis

The candidate is not demonstrably better than the PR fix. Self-review found a major hot-path allocation issue and a UIKit semantic risk around negative AdditionalSafeAreaInsets.Bottom. Compared with the PR fix, it is substantially more complex and less directly tied to the controller edge-extension policy causing the bug.


Report — Final Recommendation

Comparative Analysis — PR #35523

Candidates Compared

Rank Candidate Test status Assessment
1 pr ❌ Gate failed, but on requested Android platform that cannot validate this iOS/MacCatalyst-only fix Best candidate. Narrowly changes NavigationRenderer bottom edge extension only for iOS/MacCatalyst 26+ under a visible translucent UITabBarController; expert review found no actionable issues.
1 pr-plus-reviewer ❌ Same supplied gate status as PR Equivalent to pr; expert reviewer produced no actionable feedback, so no sandbox changes were applied.
3 try-fix-1 ⚠️ Blocked Moves ownership to TabbedRenderer and mutates every child controller's EdgesForExtendedLayout. Risk: clearing UIRectEdge.Bottom can remove unrelated child state when the tab bar becomes opaque/hidden.
4 try-fix-2 ⚠️ Blocked Extends the selected child native frame in ViewDidLayoutSubviews. Risk: post-layout frame mutation can desynchronize UIKit/MAUI layout and hit-testing, and the candidate diff duplicated SetControllers().
5 try-fix-3 ⚠️ Blocked Applies renderer-owned negative bottom AdditionalSafeAreaInsets compensation. Risk: substantially more complex, allocates in layout paths, and relies on fragile negative safe-area semantics.

Regression/Test Rule Application

The supplied gate result says the gate failed and must not be re-run. However, every available candidate is either marked failed by that supplied gate (pr/pr-plus-reviewer) or blocked because Android cannot validate the iOS/MacCatalyst-only behavior (try-fix-*). The rule that failed-regression candidates rank below passing candidates does not change the outcome because there are no passing candidates.

Decision

Winner: pr.

pr and pr-plus-reviewer are functionally identical because expert review produced no actionable changes. The raw PR is selected as the single winner because it is the simplest candidate, has no expert-review findings, and avoids the additional state mutation/layout/safe-area risks introduced by all try-fix alternatives.


Future Action — review latest findings

No alternative fix was selected for this run. Review the session findings and CI results before merging.

@kubaflo kubaflo changed the base branch from main to inflight/current June 5, 2026 12:11
@kubaflo kubaflo merged commit ff4bfc3 into dotnet:inflight/current Jun 5, 2026
22 of 31 checks passed
@github-actions github-actions Bot added this to the .NET 10.0 SR8 milestone Jun 5, 2026
PureWeen pushed a commit that referenced this pull request Jun 11, 2026
… floating glass tab bar (#35523)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Issue Details
- On iOS 26, pages inside a NavigationPage hosted in a TabbedPage do not
extend behind the new floating glass tab bar, leaving a white gap
between the page content and the tab bar.

### Root Cause
- On iOS 26, the tab bar changed from a solid bar to a floating glass
overlay. ParentingViewController.ViewWillAppear was assigning
EdgesForExtendedLayout = UIRectEdge.None for opaque navigation bars,
which prevented content from extending under the tab bar — leaving a
white gap between the page content and the new floating glass bar.

### Description of Change
- Updated NavigationRenderer to extend content layout behind the
floating tab bar when running on iOS/Mac Catalyst 26+ and the tab bar is
visible, preventing content from being clipped.

### Issues Fixed
Fixes #35490

### Validated the behaviour in the following platforms

- [ ] Windows
- [ ] Android
- [x] iOS
- [x] Mac

### Output
| Before | After |
|----------|----------|
| <video
src="https://github.com/user-attachments/assets/c4544467-6224-4dd4-bfd7-02c53bca3e8b">
| <video
src="https://github.com/user-attachments/assets/6c7186cd-3e42-4d9c-ad32-5f515a724991">
|
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

IOS Glass UI - TabbedPage with a Navigation Page - page cuts off above native floating tab bar

8 participants