[iOS] Fix Switch ThumbColor reset on iOS 26+ theme changes.#33953
Conversation
|
/azp run maui-pr-uitests |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/rebase |
efb01ce to
5fef81c
Compare
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 33953Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 33953" |
f5b70f6 to
6a2e393
Compare
There was a problem hiding this comment.
Pull request overview
Fixes an iOS/MacCatalyst 26+ behavior where UISwitch.ThumbTintColor gets reset during theme (light/dark) changes by re-applying the custom thumb color after trait changes and adding a UI test scenario.
Changes:
- Register for
UITraitUserInterfaceStylechanges on iOS/MacCatalyst 26+ and re-applyThumbColor. - Add a delayed re-apply path for thumb color to allow UIKit styling to finish.
- Add a new issue page + UI test coverage for the theme-change scenario.
Reviewed changes
Copilot reviewed 3 out of 13 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/Core/src/Handlers/Switch/SwitchHandler.iOS.cs | Re-applies thumb color on trait (theme) changes for iOS/MacCatalyst 26+. |
| src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33783.cs | Adds screenshot-based UI tests for switching themes. |
| src/Controls/tests/TestCases.HostApp/Issues/Issue33783.cs | Adds a host app repro page with theme toggle buttons and a custom-colored switch. |
kubaflo
left a comment
There was a problem hiding this comment.
Looks like the test succeeds without a fix
|
/azp run maui-pr-uitests |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/rebase |
f60367d to
7750db7
Compare
|
Azure Pipelines successfully started running 1 pipeline(s). |
🚦 Gate - Test Before and After Fix📊 Expand Full Gate —
|
| Test | Without Fix (expect FAIL) | With Fix (expect PASS) |
|---|---|---|
🖥️ Issue33783 Issue33783 |
❌ PASS — 227s | ✅ PASS — 93s |
🔴 Without fix — 🖥️ Issue33783: PASS ❌ · 227s
Determining projects to restore...
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/BindingSourceGen/Controls.BindingSourceGen.csproj (in 644 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Graphics/src/Graphics/Graphics.csproj (in 968 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Essentials/src/Essentials.csproj (in 11.37 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/Foldable/src/Controls.Foldable.csproj (in 13.59 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/Xaml/Controls.Xaml.csproj (in 13.61 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/Maps/src/Controls.Maps.csproj (in 13.62 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/Core/Controls.Core.csproj (in 13.62 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/Core/maps/src/Maps.csproj (in 13.62 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj (in 13.62 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/BlazorWebView/src/Maui/Microsoft.AspNetCore.Components.WebView.Maui.csproj (in 13.62 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj (in 13.63 sec).
/Users/cloudtest/vss/_work/1/s/.dotnet/packs/Microsoft.iOS.Sdk.net10.0_26.0/26.0.11017/targets/Xamarin.Shared.Sdk.targets(309,3): warning : RuntimeIdentifier was set on the command line, and will override the value for RuntimeIdentifiers set in the project file. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-ios]
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13788332
Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Debug/net10.0-ios26.0/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13788332
Essentials -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Essentials/Debug/net10.0-ios26.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13788332
Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Core/Debug/net10.0-ios26.0/Microsoft.Maui.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13788332
Maps -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Maps/Debug/net10.0-ios26.0/Microsoft.Maui.Maps.dll
Controls.BindingSourceGen -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13788332
Controls.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core/Debug/net10.0-ios26.0/Microsoft.Maui.Controls.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13788332
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13788332
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13788332
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13788332
Microsoft.AspNetCore.Components.WebView.Maui -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Microsoft.AspNetCore.Components.WebView.Maui/Debug/net10.0-ios26.0/Microsoft.AspNetCore.Components.WebView.Maui.dll
Controls.Maps -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Maps/Debug/net10.0-ios26.0/Microsoft.Maui.Controls.Maps.dll
Controls.Foldable -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Foldable/Debug/net10.0-ios26.0/Microsoft.Maui.Controls.Foldable.dll
Controls.Xaml -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml/Debug/net10.0-ios26.0/Microsoft.Maui.Controls.Xaml.dll
Detected signing identity:
Code Signing Key: "" (-)
Provisioning Profile: "" () - no entitlements
Bundle Id: com.microsoft.maui.uitests
App Id: com.microsoft.maui.uitests
Controls.TestCases.HostApp -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-ios/iossimulator-arm64/Controls.TestCases.HostApp.dll
Optimizing assemblies for size may change the behavior of the app. Be sure to test after publishing. See: https://aka.ms/dotnet-illink
Optimizing assemblies for size. This process might take a while.
Build succeeded.
/Users/cloudtest/vss/_work/1/s/.dotnet/packs/Microsoft.iOS.Sdk.net10.0_26.0/26.0.11017/targets/Xamarin.Shared.Sdk.targets(309,3): warning : RuntimeIdentifier was set on the command line, and will override the value for RuntimeIdentifiers set in the project file. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-ios]
1 Warning(s)
0 Error(s)
Time Elapsed 00:01:42.65
Determining projects to restore...
Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/UITest.Core/UITest.Core.csproj (in 676 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/VisualTestUtils/VisualTestUtils.csproj (in 676 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/tests/CustomAttributes/Controls.CustomAttributes.csproj (in 676 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Essentials/src/Essentials.csproj (in 693 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/BindingSourceGen/Controls.BindingSourceGen.csproj (in 677 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Graphics/src/Graphics/Graphics.csproj (in 675 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/Core/Controls.Core.csproj (in 1.03 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj (in 530 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/UITest.NUnit/UITest.NUnit.csproj (in 1.54 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/UITest.Appium/UITest.Appium.csproj (in 2.12 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/UITest.Analyzers/UITest.Analyzers.csproj (in 3.78 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/VisualTestUtils.MagickNet/VisualTestUtils.MagickNet.csproj (in 11.83 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/tests/TestCases.iOS.Tests/Controls.TestCases.iOS.Tests.csproj (in 12.57 sec).
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13788332
Controls.CustomAttributes -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.CustomAttributes/Debug/net10.0/Controls.CustomAttributes.dll
Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13788332
Essentials -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13788332
Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Core/Debug/net10.0/Microsoft.Maui.dll
Controls.BindingSourceGen -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13788332
Controls.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
UITest.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.Core/Debug/net10.0/UITest.Core.dll
VisualTestUtils -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/VisualTestUtils/Debug/netstandard2.0/VisualTestUtils.dll
UITest.NUnit -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.NUnit/Debug/net10.0/UITest.NUnit.dll
UITest.Appium -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.Appium/Debug/net10.0/UITest.Appium.dll
VisualTestUtils.MagickNet -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/VisualTestUtils.MagickNet/Debug/netstandard2.0/VisualTestUtils.MagickNet.dll
UITest.Analyzers -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.Analyzers/Debug/netstandard2.0/UITest.Analyzers.dll
Controls.TestCases.iOS.Tests -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.iOS.Tests/Debug/net10.0/Controls.TestCases.iOS.Tests.dll
Test run for /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.iOS.Tests/Debug/net10.0/Controls.TestCases.iOS.Tests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (arm64)
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
/Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.iOS.Tests/Debug/net10.0/Controls.TestCases.iOS.Tests.dll
[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.04] Discovering: Controls.TestCases.iOS.Tests
[xUnit.net 00:00:00.14] Discovered: Controls.TestCases.iOS.Tests
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.iOS.Tests/Debug/net10.0/Controls.TestCases.iOS.Tests.dll
NUnit3TestExecutor discovered 2 of 2 NUnit test cases using Current Discovery mode, Non-Explicit run
>>>>> 4/9/2026 7:55:29 AM FixtureSetup for Issue33783(iOS)
>>>>> 4/9/2026 7:55:33 AM VerifySwitchThumbColorOnDarkThemeChange Start
>>>>> 4/9/2026 7:55:34 AM VerifySwitchThumbColorOnDarkThemeChange Stop
Passed VerifySwitchThumbColorOnDarkThemeChange [1 s]
>>>>> 4/9/2026 7:55:34 AM VerifySwitchThumbColorOnLightThemeChange Start
>>>>> 4/9/2026 7:55:36 AM VerifySwitchThumbColorOnLightThemeChange Stop
Passed VerifySwitchThumbColorOnLightThemeChange [1 s]
NUnit Adapter 4.5.0.0: Test execution complete
Test Run Successful.
Total tests: 2
Passed: 2
Total time: 1.0360 Minutes
🟢 With fix — 🖥️ Issue33783: PASS ✅ · 93s
Determining projects to restore...
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/BindingSourceGen/Controls.BindingSourceGen.csproj (in 388 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Graphics/src/Graphics/Graphics.csproj (in 393 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Essentials/src/Essentials.csproj (in 398 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj (in 424 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/Core/Controls.Core.csproj (in 437 ms).
6 of 11 projects are up-to-date for restore.
/Users/cloudtest/vss/_work/1/s/.dotnet/packs/Microsoft.iOS.Sdk.net10.0_26.0/26.0.11017/targets/Xamarin.Shared.Sdk.targets(309,3): warning : RuntimeIdentifier was set on the command line, and will override the value for RuntimeIdentifiers set in the project file. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-ios]
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13788332
Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Debug/net10.0-ios26.0/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13788332
Essentials -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Essentials/Debug/net10.0-ios26.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13788332
Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Core/Debug/net10.0-ios26.0/Microsoft.Maui.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13788332
Maps -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Maps/Debug/net10.0-ios26.0/Microsoft.Maui.Maps.dll
Controls.BindingSourceGen -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13788332
Controls.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core/Debug/net10.0-ios26.0/Microsoft.Maui.Controls.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13788332
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13788332
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13788332
Controls.Maps -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Maps/Debug/net10.0-ios26.0/Microsoft.Maui.Controls.Maps.dll
Controls.Xaml -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml/Debug/net10.0-ios26.0/Microsoft.Maui.Controls.Xaml.dll
Controls.Foldable -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Foldable/Debug/net10.0-ios26.0/Microsoft.Maui.Controls.Foldable.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13788332
Microsoft.AspNetCore.Components.WebView.Maui -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Microsoft.AspNetCore.Components.WebView.Maui/Debug/net10.0-ios26.0/Microsoft.AspNetCore.Components.WebView.Maui.dll
Detected signing identity:
Code Signing Key: "" (-)
Provisioning Profile: "" () - no entitlements
Bundle Id: com.microsoft.maui.uitests
App Id: com.microsoft.maui.uitests
Controls.TestCases.HostApp -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-ios/iossimulator-arm64/Controls.TestCases.HostApp.dll
Optimizing assemblies for size may change the behavior of the app. Be sure to test after publishing. See: https://aka.ms/dotnet-illink
Optimizing assemblies for size. This process might take a while.
Build succeeded.
/Users/cloudtest/vss/_work/1/s/.dotnet/packs/Microsoft.iOS.Sdk.net10.0_26.0/26.0.11017/targets/Xamarin.Shared.Sdk.targets(309,3): warning : RuntimeIdentifier was set on the command line, and will override the value for RuntimeIdentifiers set in the project file. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-ios]
1 Warning(s)
0 Error(s)
Time Elapsed 00:00:44.64
Determining projects to restore...
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/BindingSourceGen/Controls.BindingSourceGen.csproj (in 412 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Graphics/src/Graphics/Graphics.csproj (in 369 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Essentials/src/Essentials.csproj (in 422 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj (in 453 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/Core/Controls.Core.csproj (in 467 ms).
8 of 13 projects are up-to-date for restore.
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13788332
Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
Controls.CustomAttributes -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.CustomAttributes/Debug/net10.0/Controls.CustomAttributes.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13788332
Essentials -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13788332
Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Core/Debug/net10.0/Microsoft.Maui.dll
Controls.BindingSourceGen -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13788332
Controls.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
UITest.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.Core/Debug/net10.0/UITest.Core.dll
VisualTestUtils -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/VisualTestUtils/Debug/netstandard2.0/VisualTestUtils.dll
UITest.Appium -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.Appium/Debug/net10.0/UITest.Appium.dll
UITest.NUnit -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.NUnit/Debug/net10.0/UITest.NUnit.dll
VisualTestUtils.MagickNet -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/VisualTestUtils.MagickNet/Debug/netstandard2.0/VisualTestUtils.MagickNet.dll
UITest.Analyzers -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.Analyzers/Debug/netstandard2.0/UITest.Analyzers.dll
Controls.TestCases.iOS.Tests -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.iOS.Tests/Debug/net10.0/Controls.TestCases.iOS.Tests.dll
Test run for /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.iOS.Tests/Debug/net10.0/Controls.TestCases.iOS.Tests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (arm64)
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
/Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.iOS.Tests/Debug/net10.0/Controls.TestCases.iOS.Tests.dll
[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.05] Discovering: Controls.TestCases.iOS.Tests
[xUnit.net 00:00:00.16] Discovered: Controls.TestCases.iOS.Tests
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.iOS.Tests/Debug/net10.0/Controls.TestCases.iOS.Tests.dll
NUnit3TestExecutor discovered 2 of 2 NUnit test cases using Current Discovery mode, Non-Explicit run
>>>>> 4/9/2026 7:57:01 AM FixtureSetup for Issue33783(iOS)
>>>>> 4/9/2026 7:57:05 AM VerifySwitchThumbColorOnDarkThemeChange Start
>>>>> 4/9/2026 7:57:07 AM VerifySwitchThumbColorOnDarkThemeChange Stop
Passed VerifySwitchThumbColorOnDarkThemeChange [1 s]
>>>>> 4/9/2026 7:57:07 AM VerifySwitchThumbColorOnLightThemeChange Start
>>>>> 4/9/2026 7:57:08 AM VerifySwitchThumbColorOnLightThemeChange Stop
Passed VerifySwitchThumbColorOnLightThemeChange [1 s]
NUnit Adapter 4.5.0.0: Test execution complete
Test Run Successful.
Total tests: 2
Passed: 2
Total time: 20.9962 Seconds
⚠️ Issues found
- ❌ Issue33783 PASSED without fix (should fail) — tests don't catch the bug
📁 Fix files reverted (2 files)
eng/pipelines/ci-copilot.ymlsrc/Core/src/Handlers/Switch/SwitchHandler.iOS.cs
🤖 AI Summary📊 Expand Full Review —
|
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #33953 | Register UITraitUserInterfaceStyle change on iOS/macCatalyst 26+; re-apply ThumbColor async (10ms delay) |
⏳ PENDING (Gate ❌ FAILED) | SwitchHandler.iOS.cs |
async void race concern; test flakiness concern |
🔧 Fix — Analysis & Comparison
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | try-fix | MauiSwitch override re-applies stored ThumbColor synchronously | subclass PASS | 3 files (new MauiSwitch.cs, SwitchHandler.iOS.cs, SwitchExtensions.cs) | Synchronous, no async delay |
| 2 | try-fix | KVO on PASS | SwitchHandler.iOS.cs + ios-26 snapshots | Also identified gate failure root cause | |
| 3 | try-fix | override in synchronous re-apply, no registration object | SwitchProxy PASS | SwitchHandler.iOS.cs | Clean override, no external registration |
| 4 | try-fix | wraps UIKit preserves adaptive color through trait changes | ThumbColor PASS | SwitchExtensions.cs only | Most idiomatic iOS 17+ approach. Single-file, minimal change |
| 5 | try-fix | Preventive property override in blocks UIKits nil writes | subclass PASS | 3 files (new MauiSwitch.cs, SwitchHandler.iOS.cs, SwitchExtensions.cs) | Most robust prevention, zero timing window |
| PR | PR #33953 | Register UITraitUserInterfaceStyle changes + `DispatchAsync(async () => { Task.Delay( FAILED |
SwitchHandler.iOS.cs | async void race; wrong iOS version in CI | Gate 10); })` |
Cross-Pollination
| Model | Round | New Ideas? | Details |
|---|---|---|---|
| became Attempt #5 (PASS) | |||
| gpt-5.3-codex | 2 | YES | Custom thumb UIImage instead of overly invasive, not pursued |
| gpt-5.4 | 2 | YES | TintColorDidChange variant of Attempt #3, not pursued |
Exhausted: further ideas are variants of existing passing approaches or increasingly invasiveYes
Selected Fix: Candidate #4 (Dynamic UIColor via UIColor. single file change in SwitchExtensions.cs, most idiomatic iOS 17+ approach, works with UIKit's color system rather than fighting itFromDynamicProvider)
📋 Report — Final Recommendation
⚠️ Final Recommendation: REQUEST CHANGES
Phase Status
| Phase | Status | Notes |
|---|---|---|
| Pre-Flight | ✅ COMPLETE | Issues #33783, #33767 — Switch ThumbColor reset on iOS/macCatalyst 26+ |
| Gate | ❌ FAILED | iOS — tests PASS without fix (iOS 18 simulator used; bug only manifests on iOS 26) |
| Try-Fix | ✅ COMPLETE | 5 attempts, all 5 PASSING; better alternatives found |
| Report | ✅ COMPLETE |
Summary
PR #33953 addresses a real bug on iOS/macCatalyst 26+ where UIKit resets UISwitch.ThumbTintColor during theme transitions. The fix is functionally correct but has several issues that warrant changes before merging:
- Gate failed — The tests pass even without the fix because the CI environment uses iOS 18, where the bug does not manifest. The snapshots must target an iOS 26 simulator to be meaningful.
- Code quality concerns — The
UpdateThumbColorhelper usesDispatchAsync(async () => { await Task.Delay(10); ... }), creating anasync voidwith an unobserved-exception risk, plus a timing race: the 10ms delayed continuation can fire afterDisconnectand apply stale state. - Better alternative found — Try-Fix Candidate Aloha System.Maui! #4 achieves the same result more idiomatically with a single-file change.
Root Cause
On iOS/macCatalyst 26+, UIKit introduced a new theming pass during UITraitUserInterfaceStyle transitions that resets UISwitch.ThumbTintColor to nil. This resets any explicitly set custom thumb color. The same reset can also occur during initial layout on iOS 26+.
Fix Quality
PR's approach (trait registration + async delay):
- ✅ Correct conceptual approach — listening for the UIKit reset event
- ✅ Properly cleans up
_traitChangeRegistrationinDisconnect - ❌
DispatchAsync(async () => { await Task.Delay(10); ... })is effectivelyasync void— unobserved exceptions fromTask.Delayor subsequent code - ❌ Race condition: the
platformViewparameter captured in the lambda can be stale ifDisconnectfires before the 10ms delay completes; while thePlatformViewweak-ref null check partially guards this, the check andplatformView.UpdateThumbColor(view)call use different references - ❌ Tests use
await Task.Delay(500)beforeVerifyScreenshot— should useVerifyScreenshot(retryTimeout: TimeSpan.FromSeconds(2))per test guidelines - ❌ Gate fails because tests pass without fix (iOS 18 CI, wrong platform for this bug)
Recommended alternative — Candidate #4 (Dynamic UIColor):
// In SwitchExtensions.UpdateThumbColor, on iOS/MacCatalyst 17+:
// Wrap the custom color in UIColor.Create(light:dark:) so UIKit treats it
// as a dynamic color and never discards it during trait/theme transitions.
public static void UpdateThumbColor(this UISwitch uiSwitch, ISwitch view)
{
if (view == null) return;
var thumbColor = view.ThumbColor;
if (thumbColor != null)
{
var platform = thumbColor.ToPlatform();
if (OperatingSystem.IsIOSVersionAtLeast(17) || OperatingSystem.IsMacCatalystVersionAtLeast(17))
uiSwitch.ThumbTintColor = UIColor.Create(traitCollection => platform);
else
uiSwitch.ThumbTintColor = platform;
}
}- ✅ Single file change (
SwitchExtensions.cs) - ✅ No callbacks, no subclass, no async dispatch, no timing windows
- ✅ Works with UIKit's color system — UIKit resolves and re-resolves dynamic colors; never resets them to nil
- ✅ Passed tests on iOS 26 simulator
Required Changes
- Fix the gate test environment — Ensure the snapshot baselines and test run target iOS 26 where the bug manifests; add ios-26 snapshot variants with correct (red) thumb color
- Fix
UpdateThumbColorasync void — Either apply Candidate Aloha System.Maui! #4's dynamic-UIColor approach (no callbacks needed), or at minimum replaceDispatchAsync(async () => ...)with aDispatchAftercall (noasync/await) and add a check thatPlatformView == platformViewbefore applying - Fix test delay pattern — Replace
await Task.Delay(500)withVerifyScreenshot(retryTimeout: TimeSpan.FromSeconds(2))per test guidelines - Verify issue I9-On macOS 26.2, the "Animate scroll" button is white by default on iOS and Maccatalyst platforms. #33767 — That issue is about a CollectionView "Animate scroll" button being white, but the PR only adds tests for Switch ThumbColor. Confirm whether the Switch fix also resolves I9-On macOS 26.2, the "Animate scroll" button is white by default on iOS and Maccatalyst platforms. #33767 or whether it is a separate issue
|
|
Azure Pipelines successfully started running 1 pipeline(s). |
<!-- 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! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Issue Details On iOS/MacCatalyst 26+, when the app theme changes (light ↔ dark), the Switch's ThumbColor resets to white instead of keeping the custom color. ### Root Cause On iOS/MacCatalyst 26+, UIKit resets the UISwitch's ThumbTintColor to its default value during theme transitions. ### Description of Change Register for trait collection changes to detect theme switches, then re-apply the custom ThumbColor after UIKit completes its styling. Validated the behavior in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Issues Fixed Fixes #33783 Fixes #33767 ### Output ScreenShot |Before|After| |--|--| | <video src="https://github.com/user-attachments/assets/aa595096-4f75-4d7e-b31e-f1f0acc24208" >| <video src="https://github.com/user-attachments/assets/386f9e6e-6df7-40c5-a3e7-59a0bde31df6">|
…3953) <!-- 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! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Issue Details On iOS/MacCatalyst 26+, when the app theme changes (light ↔ dark), the Switch's ThumbColor resets to white instead of keeping the custom color. ### Root Cause On iOS/MacCatalyst 26+, UIKit resets the UISwitch's ThumbTintColor to its default value during theme transitions. ### Description of Change Register for trait collection changes to detect theme switches, then re-apply the custom ThumbColor after UIKit completes its styling. Validated the behavior in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Issues Fixed Fixes dotnet#33783 Fixes dotnet#33767 ### Output ScreenShot |Before|After| |--|--| | <video src="https://github.com/user-attachments/assets/aa595096-4f75-4d7e-b31e-f1f0acc24208" >| <video src="https://github.com/user-attachments/assets/386f9e6e-6df7-40c5-a3e7-59a0bde31df6">|
<!-- 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! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Issue Details On iOS/MacCatalyst 26+, when the app theme changes (light ↔ dark), the Switch's ThumbColor resets to white instead of keeping the custom color. ### Root Cause On iOS/MacCatalyst 26+, UIKit resets the UISwitch's ThumbTintColor to its default value during theme transitions. ### Description of Change Register for trait collection changes to detect theme switches, then re-apply the custom ThumbColor after UIKit completes its styling. Validated the behavior in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Issues Fixed Fixes #33783 Fixes #33767 ### Output ScreenShot |Before|After| |--|--| | <video src="https://github.com/user-attachments/assets/aa595096-4f75-4d7e-b31e-f1f0acc24208" >| <video src="https://github.com/user-attachments/assets/386f9e6e-6df7-40c5-a3e7-59a0bde31df6">|
<!-- 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! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Issue Details On iOS/MacCatalyst 26+, when the app theme changes (light ↔ dark), the Switch's ThumbColor resets to white instead of keeping the custom color. ### Root Cause On iOS/MacCatalyst 26+, UIKit resets the UISwitch's ThumbTintColor to its default value during theme transitions. ### Description of Change Register for trait collection changes to detect theme switches, then re-apply the custom ThumbColor after UIKit completes its styling. Validated the behavior in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Issues Fixed Fixes #33783 Fixes #33767 ### Output ScreenShot |Before|After| |--|--| | <video src="https://github.com/user-attachments/assets/aa595096-4f75-4d7e-b31e-f1f0acc24208" >| <video src="https://github.com/user-attachments/assets/386f9e6e-6df7-40c5-a3e7-59a0bde31df6">|
<!-- 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! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Issue Details On iOS/MacCatalyst 26+, when the app theme changes (light ↔ dark), the Switch's ThumbColor resets to white instead of keeping the custom color. ### Root Cause On iOS/MacCatalyst 26+, UIKit resets the UISwitch's ThumbTintColor to its default value during theme transitions. ### Description of Change Register for trait collection changes to detect theme switches, then re-apply the custom ThumbColor after UIKit completes its styling. Validated the behavior in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Issues Fixed Fixes #33783 Fixes #33767 ### Output ScreenShot |Before|After| |--|--| | <video src="https://github.com/user-attachments/assets/aa595096-4f75-4d7e-b31e-f1f0acc24208" >| <video src="https://github.com/user-attachments/assets/386f9e6e-6df7-40c5-a3e7-59a0bde31df6">|
<!-- 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! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Issue Details On iOS/MacCatalyst 26+, when the app theme changes (light ↔ dark), the Switch's ThumbColor resets to white instead of keeping the custom color. ### Root Cause On iOS/MacCatalyst 26+, UIKit resets the UISwitch's ThumbTintColor to its default value during theme transitions. ### Description of Change Register for trait collection changes to detect theme switches, then re-apply the custom ThumbColor after UIKit completes its styling. Validated the behavior in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Issues Fixed Fixes #33783 Fixes #33767 ### Output ScreenShot |Before|After| |--|--| | <video src="https://github.com/user-attachments/assets/aa595096-4f75-4d7e-b31e-f1f0acc24208" >| <video src="https://github.com/user-attachments/assets/386f9e6e-6df7-40c5-a3e7-59a0bde31df6">|
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/MacCatalyst 26+, when the app theme changes (light ↔ dark), the Switch's ThumbColor resets to white instead of keeping the custom color.
Root Cause
On iOS/MacCatalyst 26+, UIKit resets the UISwitch's ThumbTintColor to its default value during theme transitions.
Description of Change
Register for trait collection changes to detect theme switches, then re-apply the custom ThumbColor after UIKit completes its styling.
Validated the behavior in the following platforms
Issues Fixed
Fixes #33783
Fixes #33767
Output ScreenShot
33783-BeforeFix.mov
33783-AfterFix.mov