[iOS] Fix Switch custom colors on iOS 26#35385
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 35385Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 35385" |
|
Hey there @@AdamEssenmacher! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed. |
There was a problem hiding this comment.
Pull request overview
This PR addresses an iOS 26 regression where UISwitch can ignore MAUI Switch custom colors by opting into UIKit’s classic sliding switch style (UISwitchStyle.Sliding) when MAUI track/thumb colors are set, while leaving default (unstyled) switches on UISwitchStyle.Automatic.
Changes:
- Updates iOS
UISwitchcolor mapping to switch styles on iOS 26+ when colors are customized, and reapply colors after style changes. - Ensures native
ThumbTintColoris cleared when MAUIThumbColoris reset tonull, and makesSwitch.ThumbColornotify the handler on change. - Adds iOS device-handler tests and a new Appium visual regression issue test/page for iOS 26 switch custom colors.
Reviewed changes
Copilot reviewed 6 out of 8 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/Core/src/Platform/iOS/SwitchExtensions.cs | Applies iOS 26+ preferred style switching and re-applies track/thumb colors when UIKit may rebuild internal views. |
| src/Controls/src/Core/Switch/Switch.cs | Adds a ThumbColor bindable-property changed callback to update the handler mapping. |
| src/Core/tests/DeviceTests/Handlers/Switch/SwitchHandlerTests.iOS.cs | Adds iOS 26 style-selection assertions and validates thumb tint clearing behavior. |
| src/Controls/tests/TestCases.HostApp/MauiProgram.cs | Allows iOS HostApp startup-page selection via the test environment variable (previously MacCatalyst-only). |
| src/Controls/tests/TestCases.HostApp/Issues/Issue35257.cs | Adds a HostApp repro page with default vs custom-colored switches for visual validation. |
| src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue35257.cs | Adds an iOS Appium screenshot test to validate initial custom color rendering. |
kubaflo
left a comment
There was a problem hiding this comment.
Looks like there some test failures caused by dark/light themes
2c8d97f to
b72e82d
Compare
- SKILL.md platform table: add /Handlers/*/iOS/, /Handlers/*/MacCatalyst/, and /Handlers/*/Windows/ to platform rows. Mirrors the Android row's handler-subdirectory pattern. iOS-directory row maps to platform/ios ONLY (not dual with platform/macos) because handler /iOS/ directories compile for iOS TFM only, unlike the *.iOS.cs file-extension pattern which compiles for both iOS and MacCatalyst. - eval.yaml PR #35461 scenario: rename to flag scope-restriction intent, add platform/android positive assertion (the PR touches Android files) and forbidden-label negatives for i/regression, partner/syncfusion, t/bug — those labels already exist on the PR but our labeler must NOT apply them. - eval.yaml PR #35385 scenario: add platform/macos and platform/windows assertions. The PR touches Platform/Windows/, Platform/Android/, and *.iOS.cs files — that last one triggers BOTH platform/ios AND platform/macos per our file-extension rule. - eval.yaml XAML scenario: rename 'issue' -> 'PR' (prompt targets a PR). - workflow.md frontmatter description: update from generic 'appropriate labels chosen from the existing repository label set' to explicitly state 'area-* and platform/* ONLY, does NOT apply triage, status, priority, type, severity, partner, regression, or any other label families'. Locked-yml regenerated by gh aw compile. Adversarial review findings deliberately NOT applied: - (?i) regex prefix: invalidated — skill-validator already passes RegexOptions.IgnoreCase and StringComparison.OrdinalIgnoreCase, so case is handled at the framework level. - output_not_contains 'area-' / 'platform/' on noop scenarios: too risky — agent prose may legitimately reference these prefixes when explaining why no labels apply. - Issue #35448 prompt change: existing-label contamination is a framework limitation (substring match in prose); not worth a scenario-level fix. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
/review -b feature/refactor-copilot-yml -p ios |
MauiBot
left a comment
There was a problem hiding this comment.
🤖 Automated review — alternative fix proposed
The expert-reviewer evaluation compared the PR fix against #2 automatically generated candidates and selected try-fix-2 as the strongest fix.
Why: try-fix-2 won because it is the only candidate with recorded passing targeted iOS Switch regression results and it preserves the native lifecycle observation required for iOS 26 color reapplication. It also improves the PR design by keeping MAUI virtual-view state and color application in SwitchProxy instead of inside the native UISwitch subclass.
Please consider applying the candidate diff below (or use it as guidance). Once you push an update, this workflow will re-trigger and re-evaluate.
Candidate diff (`try-fix-2`)
diff --git a/src/Core/src/Handlers/Switch/SwitchHandler.iOS.cs b/src/Core/src/Handlers/Switch/SwitchHandler.iOS.cs
index 20bad79c73..dcfaa11880 100644
--- a/src/Core/src/Handlers/Switch/SwitchHandler.iOS.cs
+++ b/src/Core/src/Handlers/Switch/SwitchHandler.iOS.cs
@@ -68,12 +68,17 @@ namespace Microsoft.Maui.Handlers
NSObject? _willEnterForegroundObserver;
NSObject? _windowDidBecomeKeyObserver;
+ bool _colorReapplyQueued;
public void Connect(ISwitch virtualView, UISwitch platformView)
{
_virtualView = new(virtualView);
_platformView = new(platformView);
- (platformView as MauiSwitch)?.Connect(virtualView);
+ if (platformView is MauiSwitch mauiSwitch)
+ {
+ mauiSwitch.ColorReapplyRequested += OnColorReapplyRequested;
+ mauiSwitch.SetNeedsColorReapply();
+ }
platformView.ValueChanged += OnControlValueChanged;
#if MACCATALYST
@@ -118,28 +123,65 @@ namespace Microsoft.Maui.Handlers
if (!platformView.On && VirtualView is ISwitch view && view.TrackColor is not null)
{
platformView.UpdateTrackColor(view);
- (platformView as MauiSwitch)?.SetNeedsColorReapply();
+ RequestColorReapply(platformView);
}
});
}
void UpdateThumbAndTrackColor(UISwitch platformView)
{
+ RequestColorReapply(platformView);
+ }
+
+ void RequestColorReapply(UISwitch platformView)
+ {
+ if (platformView is MauiSwitch mauiSwitch)
+ {
+ mauiSwitch.SetNeedsColorReapply();
+ }
+ else
+ {
+ QueueColorReapply(platformView);
+ }
+ }
+
+ void OnColorReapplyRequested(object? sender, EventArgs e)
+ {
+ if (sender is UISwitch platformView)
+ {
+ QueueColorReapply(platformView);
+ }
+ }
+
+ void QueueColorReapply(UISwitch platformView)
+ {
+ if (_colorReapplyQueued)
+ {
+ return;
+ }
+
+ _colorReapplyQueued = true;
+
DispatchQueue.MainQueue.DispatchAsync(() =>
{
- if (VirtualView is not ISwitch view || PlatformView is null)
+ _colorReapplyQueued = false;
+
+ if (VirtualView is not ISwitch view || PlatformView is null || !platformView.IsReadyForColorReapply())
return;
platformView.UpdateTrackColor(view);
platformView.UpdateThumbColor(view);
- (platformView as MauiSwitch)?.SetNeedsColorReapply();
});
}
public void Disconnect(UISwitch platformView)
{
platformView.ValueChanged -= OnControlValueChanged;
- (platformView as MauiSwitch)?.Disconnect();
+ if (platformView is MauiSwitch mauiSwitch)
+ {
+ mauiSwitch.ColorReapplyRequested -= OnColorReapplyRequested;
+ mauiSwitch.Disconnect();
+ }
if (_willEnterForegroundObserver is not null)
{
diff --git a/src/Core/src/Platform/iOS/MauiSwitch.cs b/src/Core/src/Platform/iOS/MauiSwitch.cs
index e56ce5bb7b..518254542e 100644
--- a/src/Core/src/Platform/iOS/MauiSwitch.cs
+++ b/src/Core/src/Platform/iOS/MauiSwitch.cs
@@ -7,30 +7,22 @@ namespace Microsoft.Maui.Platform
{
internal class MauiSwitch : UISwitch
{
- WeakReference<ISwitch>? _virtualView;
bool _colorReapplyQueued;
- bool _isReapplyingColors;
- bool _needsColorReapply;
- public MauiSwitch(CGRect frame) : base(frame)
- {
- }
+ internal event EventHandler? ColorReapplyRequested;
- public void Connect(ISwitch virtualView)
+ public MauiSwitch(CGRect frame) : base(frame)
{
- _virtualView = new(virtualView);
- SetNeedsColorReapply();
}
public void Disconnect()
{
- _virtualView = null;
- _needsColorReapply = false;
+ ColorReapplyRequested = null;
+ _colorReapplyQueued = false;
}
public void SetNeedsColorReapply()
{
- _needsColorReapply = true;
SetNeedsLayout();
QueueColorReapply();
}
@@ -58,7 +50,7 @@ namespace Microsoft.Maui.Platform
void QueueColorReapply()
{
- if (_colorReapplyQueued || !_needsColorReapply)
+ if (_colorReapplyQueued)
{
return;
}
@@ -68,34 +60,8 @@ namespace Microsoft.Maui.Platform
DispatchQueue.MainQueue.DispatchAsync(() =>
{
_colorReapplyQueued = false;
- TryReapplyColors();
+ ColorReapplyRequested?.Invoke(this, EventArgs.Empty);
});
}
-
- void TryReapplyColors()
- {
- if (_isReapplyingColors || !_needsColorReapply || !this.IsReadyForColorReapply())
- {
- return;
- }
-
- if (_virtualView is null || !_virtualView.TryGetTarget(out var virtualView))
- {
- return;
- }
-
- _isReapplyingColors = true;
-
- try
- {
- this.ApplyTrackColor(virtualView);
- this.ApplyThumbColor(virtualView);
- _needsColorReapply = false;
- }
- finally
- {
- _isReapplyingColors = false;
- }
- }
}
}
|
I’m open to trying the I agree the architecture is appealing: The reason I haven’t applied it directly is that the current fix is more targeted and preserves the existing switch-specific state machine:
So the current PR is not introducing a completely separate competing pattern; it is extending the existing switch handler split. The tradeoff is that I’m happy to go that route if we agree the cleaner boundary is worth the broader production refactor in this PR. Otherwise, I think the current targeted fix plus the test hardening is the lower-risk path for the iOS 26 regression. |
|
/review -b feature/refactor-copilot-yml -p ios |
MauiBot
left a comment
There was a problem hiding this comment.
Expert Review — 1 findings
See inline comments for details.
|
/review -b feature/refactor-copilot-yml -p ios |
MauiBot
left a comment
There was a problem hiding this comment.
Expert Review — 1 findings
See inline comments for details.
|
/review -b feature/refactor-copilot-yml -p ios |
MauiBot
left a comment
There was a problem hiding this comment.
Expert Review — 1 findings
See inline comments for details.
|
/review -b feature/refactor-copilot-yml |
MauiBot
left a comment
There was a problem hiding this comment.
Expert Review — 2 findings
See inline comments for details.
|
|
||
| try | ||
| { | ||
| this.ApplyTrackColor(virtualView); |
There was a problem hiding this comment.
[major] Native defaults preservation — TryReapplyColors reapplies track/thumb colors even when both TrackColor and ThumbColor are null. For an uncustomized off switch on iOS/MacCatalyst 26, the style can remain Automatic, but ApplyTrackColor still writes SecondarySystemFill into the internal track subview and ApplyThumbColor writes null into ThumbTintColor, so layout/trait/window reapply paths can mutate UIKit's native Liquid Glass/default rendering. Please gate reapply on custom-color presence, or make the low-level apply methods no-op when the switch is Automatic with no custom colors, and add a regression test that verifies default/native rendering is preserved rather than only checking PreferredStyle.
|
/review -b feature/refactor-copilot-yml -p ios |
🤖 AI Summary
📊 Review Session —
|
| Test | Without Fix (expect FAIL) | With Fix (expect PASS) |
|---|---|---|
📱 SwitchHandlerTests (DefaultSwitchReappliesLegacyOffTrackColorBeforeiOSOrMacCatalyst26, CustomColorsUseSlidingStyleOniOSOrMacCatalyst26, CustomColorsRenderOnInitialOffStateOniOSOrMacCatalyst26, DefaultSwitchUsesAutomaticStyleOniOSOrMacCatalyst26, ThumbColorClearsWhenResetOniOSOrMacCatalyst26, CustomColorsClearToAutomaticStyleOniOSOrMacCatalyst26, CustomColorsReapplyAfterMovedToWindowOniOSOrMacCatalyst26, CustomColorsUpdateAfterAppThemeChangeOniOSOrMacCatalyst26) Category=Switch |
🛠️ BUILD ERROR | ✅ PASS — 406s |
🔴 Without fix — 📱 SwitchHandlerTests (DefaultSwitchReappliesLegacyOffTrackColorBeforeiOSOrMacCatalyst26, CustomColorsUseSlidingStyleOniOSOrMacCatalyst26, CustomColorsRenderOnInitialOffStateOniOSOrMacCatalyst26, DefaultSwitchUsesAutomaticStyleOniOSOrMacCatalyst26, ThumbColorClearsWhenResetOniOSOrMacCatalyst26, CustomColorsClearToAutomaticStyleOniOSOrMacCatalyst26, CustomColorsReapplyAfterMovedToWindowOniOSOrMacCatalyst26, CustomColorsUpdateAfterAppThemeChangeOniOSOrMacCatalyst26): 🛠️ BUILD ERROR · 29s
Determining projects to restore...
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/BindingSourceGen/Controls.BindingSourceGen.csproj (in 664 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/Graphics/src/Graphics/Graphics.csproj (in 943 ms).
Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/DeviceTests.Runners.SourceGen/TestUtils.DeviceTests.Runners.SourceGen.csproj (in 4.89 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/Essentials/src/Essentials.csproj (in 4.98 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/Core/tests/DeviceTests.Shared/Core.DeviceTests.Shared.csproj (in 4.76 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/DeviceTests.Runners/TestUtils.DeviceTests.Runners.csproj (in 5.03 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/Core/Controls.Core.csproj (in 5.71 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/Xaml/Controls.Xaml.csproj (in 5.72 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/DeviceTests/TestUtils.DeviceTests.csproj (in 5.74 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj (in 5.73 sec).
Restored /Users/cloudtest/vss/_work/1/s/src/Core/tests/DeviceTests/Core.DeviceTests.csproj (in 5.78 sec).
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14232291
Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Release/net10.0-ios26.0/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14232291
Essentials -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Essentials/Release/net10.0-ios26.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14232291
/Users/cloudtest/vss/_work/1/s/src/Core/src/Platform/iOS/MauiSwitch.cs(36,43): error CS1061: 'ISwitch' does not contain a definition for 'ShouldPreserveNativeDefaults' and no accessible extension method 'ShouldPreserveNativeDefaults' accepting a first argument of type 'ISwitch' could be found (are you missing a using directive or an assembly reference?) [/Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj::TargetFramework=net10.0-ios26.0]
/Users/cloudtest/vss/_work/1/s/src/Core/src/Platform/iOS/MauiSwitch.cs(93,43): error CS1061: 'ISwitch' does not contain a definition for 'ShouldPreserveNativeDefaults' and no accessible extension method 'ShouldPreserveNativeDefaults' accepting a first argument of type 'ISwitch' could be found (are you missing a using directive or an assembly reference?) [/Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj::TargetFramework=net10.0-ios26.0]
/Users/cloudtest/vss/_work/1/s/src/Core/src/Platform/iOS/MauiSwitch.cs(99,14): error CS1061: 'MauiSwitch' does not contain a definition for 'IsReadyForColorReapply' and no accessible extension method 'IsReadyForColorReapply' accepting a first argument of type 'MauiSwitch' could be found (are you missing a using directive or an assembly reference?) [/Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj::TargetFramework=net10.0-ios26.0]
/Users/cloudtest/vss/_work/1/s/src/Core/src/Platform/iOS/MauiSwitch.cs(108,10): error CS1061: 'MauiSwitch' does not contain a definition for 'ApplyTrackColor' and no accessible extension method 'ApplyTrackColor' accepting a first argument of type 'MauiSwitch' could be found (are you missing a using directive or an assembly reference?) [/Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj::TargetFramework=net10.0-ios26.0]
/Users/cloudtest/vss/_work/1/s/src/Core/src/Platform/iOS/MauiSwitch.cs(109,10): error CS1061: 'MauiSwitch' does not contain a definition for 'ApplyThumbColor' and no accessible extension method 'ApplyThumbColor' accepting a first argument of type 'MauiSwitch' could be found (are you missing a using directive or an assembly reference?) [/Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj::TargetFramework=net10.0-ios26.0]
Build FAILED.
/Users/cloudtest/vss/_work/1/s/src/Core/src/Platform/iOS/MauiSwitch.cs(36,43): error CS1061: 'ISwitch' does not contain a definition for 'ShouldPreserveNativeDefaults' and no accessible extension method 'ShouldPreserveNativeDefaults' accepting a first argument of type 'ISwitch' could be found (are you missing a using directive or an assembly reference?) [/Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj::TargetFramework=net10.0-ios26.0]
/Users/cloudtest/vss/_work/1/s/src/Core/src/Platform/iOS/MauiSwitch.cs(93,43): error CS1061: 'ISwitch' does not contain a definition for 'ShouldPreserveNativeDefaults' and no accessible extension method 'ShouldPreserveNativeDefaults' accepting a first argument of type 'ISwitch' could be found (are you missing a using directive or an assembly reference?) [/Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj::TargetFramework=net10.0-ios26.0]
/Users/cloudtest/vss/_work/1/s/src/Core/src/Platform/iOS/MauiSwitch.cs(99,14): error CS1061: 'MauiSwitch' does not contain a definition for 'IsReadyForColorReapply' and no accessible extension method 'IsReadyForColorReapply' accepting a first argument of type 'MauiSwitch' could be found (are you missing a using directive or an assembly reference?) [/Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj::TargetFramework=net10.0-ios26.0]
/Users/cloudtest/vss/_work/1/s/src/Core/src/Platform/iOS/MauiSwitch.cs(108,10): error CS1061: 'MauiSwitch' does not contain a definition for 'ApplyTrackColor' and no accessible extension method 'ApplyTrackColor' accepting a first argument of type 'MauiSwitch' could be found (are you missing a using directive or an assembly reference?) [/Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj::TargetFramework=net10.0-ios26.0]
/Users/cloudtest/vss/_work/1/s/src/Core/src/Platform/iOS/MauiSwitch.cs(109,10): error CS1061: 'MauiSwitch' does not contain a definition for 'ApplyThumbColor' and no accessible extension method 'ApplyThumbColor' accepting a first argument of type 'MauiSwitch' could be found (are you missing a using directive or an assembly reference?) [/Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj::TargetFramework=net10.0-ios26.0]
0 Warning(s)
5 Error(s)
Time Elapsed 00:00:18.53
🟢 With fix — 📱 SwitchHandlerTests (DefaultSwitchReappliesLegacyOffTrackColorBeforeiOSOrMacCatalyst26, CustomColorsUseSlidingStyleOniOSOrMacCatalyst26, CustomColorsRenderOnInitialOffStateOniOSOrMacCatalyst26, DefaultSwitchUsesAutomaticStyleOniOSOrMacCatalyst26, ThumbColorClearsWhenResetOniOSOrMacCatalyst26, CustomColorsClearToAutomaticStyleOniOSOrMacCatalyst26, CustomColorsReapplyAfterMovedToWindowOniOSOrMacCatalyst26, CustomColorsUpdateAfterAppThemeChangeOniOSOrMacCatalyst26): PASS ✅ · 406s
(truncated to last 15,000 chars)
07:26:19.689087-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Native View Bounding Box is not empty
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:19.6945610] 2026-05-29 07:26:19.694255-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Native View Bounding Box is not empty
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:19.6988110] 2026-05-29 07:26:19.698370-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Native View Bounding Box is not empty
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:19.9138860] 2026-05-29 07:26:19.913606-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Thumb Color Clears When Reset On iOS/MacCatalyst 26
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:19.9210460] 2026-05-29 07:26:19.920597-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] ContainerView Adds And Removes
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:19.9400970] 2026-05-29 07:26:19.939677-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] ContainerView Remains If Shadow Mapper Runs Again
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:19.9414460] 2026-05-29 07:26:19.940984-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [IGNORED] View Renders To Image
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:19.9462870] 2026-05-29 07:26:19.945978-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Semantic Description is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:20.9271720] 2026-05-29 07:26:20.926771-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Custom Colors Update After App Theme Change On iOS/MacCatalyst 26
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.2456590] 2026-05-29 07:26:21.245362-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Custom Colors Clear To Automatic Style On iOS/MacCatalyst 26
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.2523820] 2026-05-29 07:26:21.252052-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] PlatformView Transforms are not empty
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.2551370] 2026-05-29 07:26:21.254525-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] PlatformView Transforms are not empty
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.2637100] 2026-05-29 07:26:21.260406-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] PlatformView Transforms are not empty
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.2640500] 2026-05-29 07:26:21.262535-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [IGNORED] ThumbColor Initializes Correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.2646240] 2026-05-29 07:26:21.264344-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Default Switch Reapplies Legacy Off Track Color Before iOS/MacCatalyst 26
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.2780430] 2026-05-29 07:26:21.277693-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Transformation Calculated Correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.2826290] 2026-05-29 07:26:21.282256-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Thumb Color Updates Correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.2901210] 2026-05-29 07:26:21.289545-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Null Thumb Color Doesn't Crash
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.5316320] 2026-05-29 07:26:21.531152-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Setting Semantic Description makes element accessible
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.5376510] 2026-05-29 07:26:21.537296-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Is Toggled Initializes Correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.5520700] 2026-05-29 07:26:21.551477-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Track Color's view is set when toggled on
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.9155980] 2026-05-29 07:26:21.915199-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Custom Colors Reapply After Moved To Window On iOS/MacCatalyst 26
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.9160500] 2026-05-29 07:26:21.915814-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Track Color's view is default color when toggled off
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.9220780] 2026-05-29 07:26:21.921645-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] FlowDirection is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.9316790] 2026-05-29 07:26:21.925906-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] FlowDirection is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.9370280] 2026-05-29 07:26:21.936743-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Opacity is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.9493790] 2026-05-29 07:26:21.948943-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Opacity is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.9595290] 2026-05-29 07:26:21.951702-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Opacity is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.9595510] 2026-05-29 07:26:21.954967-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Opacity is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.9595550] 2026-05-29 07:26:21.957709-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Opacity is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.9698500] 2026-05-29 07:26:21.967182-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Scale initializes correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.9799170] 2026-05-29 07:26:21.969924-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Scale initializes correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.9799350] 2026-05-29 07:26:21.973246-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Scale initializes correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.9799390] 2026-05-29 07:26:21.977969-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Scale initializes correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.9893920] 2026-05-29 07:26:21.980025-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Scale initializes correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.9894380] 2026-05-29 07:26:21.982929-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Scale initializes correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.9894540] 2026-05-29 07:26:21.986368-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Scale initializes correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.9923250] 2026-05-29 07:26:21.991294-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Scale initializes correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:21.9956600] 2026-05-29 07:26:21.995321-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Scale initializes correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.0031710] 2026-05-29 07:26:22.002840-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Semantic Hint is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.0188690] 2026-05-29 07:26:22.018470-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] DisconnectHandlerDoesntCrash
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.0196520] 2026-05-29 07:26:22.019381-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] HandlersHaveAllExpectedContructors
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.0252590] 2026-05-29 07:26:22.024941-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Rotation initializes correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.0283440] 2026-05-29 07:26:22.028064-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Rotation initializes correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.0307610] 2026-05-29 07:26:22.030516-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Rotation initializes correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.0455000] 2026-05-29 07:26:22.044793-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Rotation initializes correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.0556420] 2026-05-29 07:26:22.048236-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Rotation initializes correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.0556680] 2026-05-29 07:26:22.051398-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Rotation initializes correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.0584170] 2026-05-29 07:26:22.058156-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Rotation initializes correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.0616150] 2026-05-29 07:26:22.061332-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Rotation initializes correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.0645020] 2026-05-29 07:26:22.064226-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Rotation initializes correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.0672950] 2026-05-29 07:26:22.066905-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Rotation initializes correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.0774340] 2026-05-29 07:26:22.069060-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Rotation initializes correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.0774640] 2026-05-29 07:26:22.074927-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Ensure UISwitch Stays Below 101 Width
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.0796500] 2026-05-29 07:26:22.079408-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Visibility is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.0837510] 2026-05-29 07:26:22.083458-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Visibility is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.0884870] 2026-05-29 07:26:22.087985-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Transformation Initialize Correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.0887640] 2026-05-29 07:26:22.088399-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [IGNORED] Updating Native Is On property updates Virtual View
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.0962240] 2026-05-29 07:26:22.095851-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Native View Bounds are not empty
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.0989840] 2026-05-29 07:26:22.098711-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Native View Bounds are not empty
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.1160920] 2026-05-29 07:26:22.115814-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Native View Bounds are not empty
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.1220030] 2026-05-29 07:26:22.121644-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] InputTransparencyInitializesCorrectly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.1258770] 2026-05-29 07:26:22.125471-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] InputTransparencyInitializesCorrectly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.4523290] 2026-05-29 07:26:22.452050-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Default Switch Uses Automatic Style On iOS/MacCatalyst 26
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.4601850] 2026-05-29 07:26:22.459840-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Custom Colors Use Sliding Style On iOS/MacCatalyst 26
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.4647290] 2026-05-29 07:26:22.462979-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Custom Colors Use Sliding Style On iOS/MacCatalyst 26
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.4757460] 2026-05-29 07:26:22.475273-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Custom Colors Use Sliding Style On iOS/MacCatalyst 26
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.4811320] 2026-05-29 07:26:22.480772-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Clip Initializes ContainerView Correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.4856360] 2026-05-29 07:26:22.485379-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Automation Id is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.4946990] 2026-05-29 07:26:22.494407-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Apple has not changed UITrack Subviews
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.4996210] 2026-05-29 07:26:22.499267-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Null Semantics Doesnt throw exception
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.7250740] 2026-05-29 07:26:22.724754-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Semantic Heading is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.9396700] 2026-05-29 07:26:22.939363-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] [PASS] Setting Semantic Hint makes element accessible
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.9408150] 2026-05-29 07:26:22.940586-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] Microsoft.Maui.DeviceTests.SwitchHandlerTests 3.5853452 ms
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.9440310] 2026-05-29 07:26:22.943785-0700 Microsoft.Maui.Core.DeviceTests[7925:68801] Tests run: 75 Passed: 72 Inconclusive: 0 Failed: 0 Ignored: 3
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.9466490] 2026-05-29 07:26:22.946465-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] Xml file was written to the provided writer.
�[40m�[37mdbug�[39m�[22m�[49m: [07:26:22.9467680] 2026-05-29 07:26:22.946607-0700 Microsoft.Maui.Core.DeviceTests[7925:68304] Tests run: 1162 Passed: 72 Inconclusive: 0 Failed: 0 Ignored: 1090
�[40m�[37mdbug�[39m�[22m�[49m: ==================== End of ApplicationLog ====================
�[40m�[37mdbug�[39m�[22m�[49m:
�[40m�[32minfo�[39m�[22m�[49m: Uninstalling the application 'com.microsoft.maui.core.devicetests' from 'iPhone 11 Pro'
�[40m�[37mdbug�[39m�[22m�[49m:
�[40m�[37mdbug�[39m�[22m�[49m: Running /Applications/Xcode_26.0.1.app/Contents/Developer/usr/bin/simctl
�[40m�[37mdbug�[39m�[22m�[49m: Process simctl exited with 0
�[40m�[32minfo�[39m�[22m�[49m: Application 'com.microsoft.maui.core.devicetests' was uninstalled successfully
�[40m�[32minfo�[39m�[22m�[49m: <<XHARNESS_RESULT_START>>
{
"version": 1,
"machineName": "H14W2369K6-1",
"exitCode": 0,
"exitCodeName": "SUCCESS",
"platform": "apple",
"device": "iPhone 11 Pro",
"deviceOsVersion": "26.0",
"files": [
{
"name": "test-ios-simulator-64_26.0-B7B5B7C3-B079-4DBB-8657-DF4690C03ECD.log",
"type": "executionlog"
},
{
"name": "list-ios-simulator-64_26.0-20260529_072541.log",
"type": "devicelist"
},
{
"name": "test-ios-simulator-64_26.0-20260529_072549.log",
"type": "testlog"
},
{
"name": "iPhone 11 Pro.log",
"type": "systemlog"
},
{
"name": "Microsoft.Maui.Core.DeviceTests.log",
"type": "systemlog"
},
{
"name": "com.microsoft.maui.core.devicetests.log",
"type": "applicationlog"
},
{
"name": "xunit-test-ios-simulator-64_26.0-20260529_072549.xml",
"type": "xmllog"
}
]
}
<<XHARNESS_RESULT_END>>
XHarness exit code: 0
Passed: 0
Failed: 0
Tests completed successfully
⚠️ Failure Details
- 🛠️ SwitchHandlerTests (DefaultSwitchReappliesLegacyOffTrackColorBeforeiOSOrMacCatalyst26, CustomColorsUseSlidingStyleOniOSOrMacCatalyst26, CustomColorsRenderOnInitialOffStateOniOSOrMacCatalyst26, DefaultSwitchUsesAutomaticStyleOniOSOrMacCatalyst26, ThumbColorClearsWhenResetOniOSOrMacCatalyst26, CustomColorsClearToAutomaticStyleOniOSOrMacCatalyst26, CustomColorsReapplyAfterMovedToWindowOniOSOrMacCatalyst26, CustomColorsUpdateAfterAppThemeChangeOniOSOrMacCatalyst26) without fix: build failed before tests could run
/Users/cloudtest/vss/_work/1/s/src/Core/src/Platform/iOS/MauiSwitch.cs(36,43): error CS1061: 'ISwitch' does not contain a definition for 'ShouldPreserveNativeDefaults' and no accessible extension meth...
📁 Fix files reverted (237 files)
eng/Signing.propseng/pipelines/ci-copilot.ymlsrc/BlazorWebView/src/Maui/Android/BlazorAndroidWebView.cssrc/BlazorWebView/src/Maui/Android/BlazorWebViewHandler.Android.cssrc/BlazorWebView/src/Maui/Android/WebKitWebViewClient.cssrc/Compatibility/Core/src/Android/Renderers/SwipeViewRenderer.cssrc/Compatibility/Core/src/MacOS/Extensions/NSMenuExtensions.cssrc/Compatibility/Core/src/iOS/EventTracker.cssrc/Compatibility/Core/src/iOS/Renderers/SwipeViewRenderer.cssrc/Controls/samples/Controls.Sample/Pages/Controls/MapsGalleries/MapPinsGallery.xamlsrc/Controls/samples/Controls.Sample/Pages/Controls/MapsGalleries/MapPinsGallery.xaml.cssrc/Controls/src/Build.Tasks/SetPropertiesVisitor.cssrc/Controls/src/Core/ActionSheetArguments.cssrc/Controls/src/Core/AlertArguments.cssrc/Controls/src/Core/BindableObject.cssrc/Controls/src/Core/BindableProperty.cssrc/Controls/src/Core/Button/Button.iOS.cssrc/Controls/src/Core/Compatibility/Android/Resources/layout/flyoutcontent.axmlsrc/Controls/src/Core/Compatibility/Handlers/FlyoutPage/iOS/PhoneFlyoutPageRenderer.cssrc/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cssrc/Controls/src/Core/Compatibility/Handlers/Shell/Android/SearchHandlerAppearanceTracker.cssrc/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellFlyoutTemplatedContentRenderer.cssrc/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellFragmentContainer.cssrc/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellItemRenderer.cssrc/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellRenderer.cssrc/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellToolbarTracker.cssrc/Controls/src/Core/Compatibility/Handlers/Shell/iOS/SearchHandlerAppearanceTracker.cssrc/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellFlyoutLayoutManager.cssrc/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellPageRendererTracker.cssrc/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellSectionRenderer.cssrc/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellSectionRootRenderer.cssrc/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellTableViewController.cssrc/Controls/src/Core/Editor/Editor.Mapper.cssrc/Controls/src/Core/Editor/Editor.iOS.cssrc/Controls/src/Core/Element/Element.cssrc/Controls/src/Core/Entry/Entry.Mapper.cssrc/Controls/src/Core/Entry/Entry.iOS.cssrc/Controls/src/Core/FlyoutPage/FlyoutPage.cssrc/Controls/src/Core/FormattedString.cssrc/Controls/src/Core/GestureElement.cssrc/Controls/src/Core/Handlers/Items/Android/Adapters/GroupableItemsViewAdapter.cssrc/Controls/src/Core/Handlers/Items/Android/Adapters/ItemsViewAdapter.cssrc/Controls/src/Core/Handlers/Items/Android/GridLayoutSpanSizeLookup.cssrc/Controls/src/Core/Handlers/Items/Android/ItemContentView.cssrc/Controls/src/Core/Handlers/Items/Android/MauiCarouselRecyclerView.cssrc/Controls/src/Core/Handlers/Items/Android/MauiRecyclerView.cssrc/Controls/src/Core/Handlers/Items/Android/TemplatedItemViewHolder.cssrc/Controls/src/Core/Handlers/Items/CarouselViewHandler.Windows.cssrc/Controls/src/Core/Handlers/Items/iOS/ItemsViewController.cssrc/Controls/src/Core/Handlers/Items/iOS/ItemsViewDelegator.cssrc/Controls/src/Core/Handlers/Items2/iOS/CarouselViewController2.cssrc/Controls/src/Core/Handlers/Items2/iOS/GroupableItemsViewController2.cssrc/Controls/src/Core/Handlers/Items2/iOS/ItemsViewController2.cssrc/Controls/src/Core/Handlers/Items2/iOS/ItemsViewDelegator2.cssrc/Controls/src/Core/Handlers/Items2/iOS/LayoutFactory2.cssrc/Controls/src/Core/Handlers/Items2/iOS/StructuredItemsViewController2.cssrc/Controls/src/Core/Handlers/Shapes/Polygon/PolygonHandler.Android.cssrc/Controls/src/Core/Handlers/Shapes/Polygon/PolygonHandler.Tizen.cssrc/Controls/src/Core/Handlers/Shapes/Polygon/PolygonHandler.Windows.cssrc/Controls/src/Core/Handlers/Shapes/Polygon/PolygonHandler.cssrc/Controls/src/Core/Handlers/Shapes/Polygon/PolygonHandler.iOS.cssrc/Controls/src/Core/Handlers/Shapes/Polyline/PolylineHandler.Android.cssrc/Controls/src/Core/Handlers/Shapes/Polyline/PolylineHandler.Tizen.cssrc/Controls/src/Core/Handlers/Shapes/Polyline/PolylineHandler.Windows.cssrc/Controls/src/Core/Handlers/Shapes/Polyline/PolylineHandler.cssrc/Controls/src/Core/Handlers/Shapes/Polyline/PolylineHandler.iOS.cssrc/Controls/src/Core/Handlers/Shell/ShellItemHandler.Windows.cssrc/Controls/src/Core/Handlers/Shell/Windows/ShellFlyoutItemView.cssrc/Controls/src/Core/Handlers/Shell/Windows/ShellView.cssrc/Controls/src/Core/Hosting/AppHostBuilderExtensions.cssrc/Controls/src/Core/ImageElement.cssrc/Controls/src/Core/Internals/WeakEventProxy.cssrc/Controls/src/Core/Items/SelectionList.cssrc/Controls/src/Core/Label/Label.Mapper.cssrc/Controls/src/Core/Label/Label.cssrc/Controls/src/Core/Label/Label.iOS.cssrc/Controls/src/Core/ListView/ListView.cssrc/Controls/src/Core/NavigationPage/NavigationPage.cssrc/Controls/src/Core/Page/Page.cssrc/Controls/src/Core/Platform/AlertManager/AlertManager.Android.cssrc/Controls/src/Core/Platform/AlertManager/AlertManager.cssrc/Controls/src/Core/Platform/Android/BottomNavigationViewUtils.cssrc/Controls/src/Core/Platform/Android/DragAndDropGestureHandler.cssrc/Controls/src/Core/Platform/Android/GenericAnimatorListener.cssrc/Controls/src/Core/Platform/Android/TabbedPageManager.cssrc/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.iOS.cssrc/Controls/src/Core/Platform/Windows/CollectionView/ScrollHelpers.cssrc/Controls/src/Core/Platform/iOS/Extensions/FormattedStringExtensions.cssrc/Controls/src/Core/Platform/iOS/Extensions/LabelExtensions.cssrc/Controls/src/Core/PromptArguments.cssrc/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txtsrc/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txtsrc/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txtsrc/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Unshipped.txtsrc/Controls/src/Core/PublicAPI/net-windows/PublicAPI.Unshipped.txtsrc/Controls/src/Core/PublicAPI/net/PublicAPI.Unshipped.txtsrc/Controls/src/Core/PublicAPI/netstandard/PublicAPI.Unshipped.txtsrc/Controls/src/Core/RadioButton/RadioButton.cssrc/Controls/src/Core/RadioButton/RadioButtonGroup.cssrc/Controls/src/Core/RadioButton/RadioButtonGroupController.cssrc/Controls/src/Core/ResourcesExtensions.cssrc/Controls/src/Core/Setter.cssrc/Controls/src/Core/Shadow.cssrc/Controls/src/Core/Shapes/Shape.cssrc/Controls/src/Core/Shell/Shell.cssrc/Controls/src/Core/Shell/ShellNavigationManager.cssrc/Controls/src/Core/SwipeView/SwipeItem.cssrc/Controls/src/Core/SwipeView/SwipeItemView.cssrc/Controls/src/Core/SwipeView/SwipeItems.cssrc/Controls/src/Core/SwipeView/SwipeView.cssrc/Controls/src/Core/TabbedPage/TabbedPage.Windows.cssrc/Controls/src/Core/VisualElement/VisualElement.cssrc/Controls/src/Core/VisualStateManager.cssrc/Controls/src/Core/WebView/WebViewSource.cssrc/Controls/src/Core/Window/Window.Android.cssrc/Controls/src/Core/Window/Window.cssrc/Controls/src/SourceGen/NodeSGExtensions.cssrc/Controls/src/Xaml/ApplyPropertiesVisitor.cssrc/Controls/src/Xaml/MarkupExtensions/OnIdiomExtension.cssrc/Controls/src/Xaml/MarkupExtensions/StaticResourceExtension.cssrc/Core/maps/src/Handlers/Map/MapHandler.Android.cssrc/Core/maps/src/Handlers/Map/MapHandler.iOS.cssrc/Core/maps/src/Handlers/MapPin/MapPinHandler.Android.cssrc/Core/maps/src/Platform/iOS/MauiMKMapView.cssrc/Core/maps/src/PublicAPI/net-android/PublicAPI.Unshipped.txtsrc/Core/src/Diagnostics/DiagnosticsManager.cssrc/Core/src/Diagnostics/IDiagnosticsManager.cssrc/Core/src/Diagnostics/Instrumentation/DiagnosticInstrumentation.cssrc/Core/src/Diagnostics/Instrumentation/LayoutArrangeInstrumentation.cssrc/Core/src/Diagnostics/Instrumentation/LayoutDiagnosticMetrics.cssrc/Core/src/Diagnostics/Instrumentation/LayoutMeasureInstrumentation.cssrc/Core/src/Graphics/MauiDrawable.Android.cssrc/Core/src/Handlers/Button/ButtonHandler.Android.cssrc/Core/src/Handlers/Button/ButtonHandler.cssrc/Core/src/Handlers/Button/ButtonHandler.iOS.cssrc/Core/src/Handlers/DatePicker/DatePickerHandler.Android.cssrc/Core/src/Handlers/DatePicker/DatePickerHandler.MacCatalyst.cssrc/Core/src/Handlers/Editor/EditorHandler.iOS.cssrc/Core/src/Handlers/Entry/EntryHandler.cssrc/Core/src/Handlers/Entry/EntryHandler.iOS.cssrc/Core/src/Handlers/FlyoutView/FlyoutViewHandler.Android.cssrc/Core/src/Handlers/HybridWebView/HybridWebViewHandler.Standard.cssrc/Core/src/Handlers/HybridWebView/HybridWebViewHandler.Tizen.cssrc/Core/src/Handlers/HybridWebView/HybridWebViewHandler.Windows.cssrc/Core/src/Handlers/HybridWebView/HybridWebViewHandler.cssrc/Core/src/Handlers/Image/ImageHandler.Windows.cssrc/Core/src/Handlers/Image/ImageHandler.iOS.cssrc/Core/src/Handlers/Label/LabelHandler.cssrc/Core/src/Handlers/Label/LabelHandler.iOS.cssrc/Core/src/Handlers/Picker/PickerHandler.iOS.cssrc/Core/src/Handlers/ProgressBar/ProgressBarHandler.iOS.cssrc/Core/src/Handlers/RadioButton/RadioButtonHandler.cssrc/Core/src/Handlers/RadioButton/RadioButtonHandler.iOS.cssrc/Core/src/Handlers/RefreshView/RefreshViewHandler.Windows.cssrc/Core/src/Handlers/ScrollView/ScrollViewHandler.Android.cssrc/Core/src/Handlers/ScrollView/ScrollViewHandler.Windows.cssrc/Core/src/Handlers/ScrollView/ScrollViewHandler.iOS.cssrc/Core/src/Handlers/SearchBar/SearchBarHandler.iOS.cssrc/Core/src/Handlers/SearchBar/SearchBarHandler2.Android.cssrc/Core/src/Handlers/ShapeView/ShapeViewHandler.Standard.cssrc/Core/src/Handlers/ShapeView/ShapeViewHandler.cssrc/Core/src/Handlers/Stepper/StepperHandler.iOS.cssrc/Core/src/Handlers/SwipeItemMenuItem/SwipeItemMenuItemHandler.Android.cssrc/Core/src/Handlers/SwipeItemMenuItem/SwipeItemMenuItemHandler.iOS.cssrc/Core/src/Handlers/Switch/SwitchHandler.iOS.cssrc/Core/src/Handlers/TimePicker/TimePickerHandler.Android.cssrc/Core/src/Handlers/TimePicker/TimePickerHandler.Windows.cssrc/Core/src/Handlers/TimePicker/TimePickerHandler.cssrc/Core/src/Handlers/TimePicker/TimePickerHandler.iOS.cssrc/Core/src/Handlers/WebView/WebViewHandler.Android.cssrc/Core/src/Hosting/EssentialsMauiAppBuilderExtensions.cssrc/Core/src/Hosting/LifecycleEvents/AppHostBuilderExtensions.Android.cssrc/Core/src/Platform/Android/ActivityIndicatorExtensions.cssrc/Core/src/Platform/Android/ActivityResultCallbackRegistry.cssrc/Core/src/Platform/Android/BorderDrawable.cssrc/Core/src/Platform/Android/ContainerView.cssrc/Core/src/Platform/Android/EditTextExtensions.cssrc/Core/src/Platform/Android/MauiAppCompatActivity.Lifecycle.cssrc/Core/src/Platform/Android/MauiAppCompatActivity.cssrc/Core/src/Platform/Android/MauiHybridWebView.cssrc/Core/src/Platform/Android/MauiHybridWebViewClient.cssrc/Core/src/Platform/Android/MauiScrollView.cssrc/Core/src/Platform/Android/MauiSearchView.cssrc/Core/src/Platform/Android/MauiSwipeRefreshLayout.cssrc/Core/src/Platform/Android/MauiSwipeView.cssrc/Core/src/Platform/Android/MauiWebView.cssrc/Core/src/Platform/Android/MauiWebViewClient.cssrc/Core/src/Platform/Android/Navigation/NavigationRootManager.cssrc/Core/src/Platform/Android/RadioButtonExtensions.cssrc/Core/src/Platform/Android/SafeAreaExtensions.cssrc/Core/src/Platform/Android/SearchViewExtensions.cssrc/Core/src/Platform/Android/TimePickerExtensions.cssrc/Core/src/Platform/Windows/ContentPanel.cssrc/Core/src/Platform/Windows/LayoutPanel.cssrc/Core/src/Platform/Windows/MauiPasswordTextBox.cssrc/Core/src/Platform/Windows/MauiToolbar.xaml.cssrc/Core/src/Platform/Windows/RadioButtonExtensions.cssrc/Core/src/Platform/Windows/RootNavigationView.cssrc/Core/src/Platform/Windows/ScrollViewerExtensions.cssrc/Core/src/Platform/Windows/TimePickerExtensions.cssrc/Core/src/Platform/Windows/WebViewExtensions.cssrc/Core/src/Platform/iOS/ButtonExtensions.cssrc/Core/src/Platform/iOS/KeyboardAcceleratorExtensions.cssrc/Core/src/Platform/iOS/LayerExtensions.cssrc/Core/src/Platform/iOS/MauiPageControl.cssrc/Core/src/Platform/iOS/MauiScrollView.cssrc/Core/src/Platform/iOS/MauiSwipeView.cssrc/Core/src/Platform/iOS/MauiTextView.cssrc/Core/src/Platform/iOS/MauiView.cssrc/Core/src/Platform/iOS/PickerExtensions.cssrc/Core/src/Platform/iOS/SwitchExtensions.cssrc/Core/src/Platform/iOS/TabbedViewExtensions.cssrc/Core/src/Platform/iOS/TextFieldExtensions.cssrc/Core/src/Platform/iOS/TimePickerExtensions.cssrc/Core/src/Platform/iOS/WrapperView.cssrc/Core/src/PublicAPI/net-android/PublicAPI.Unshipped.txtsrc/Core/src/PublicAPI/net-ios/PublicAPI.Unshipped.txtsrc/Core/src/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txtsrc/Core/src/PublicAPI/net-windows/PublicAPI.Unshipped.txtsrc/Core/src/ViewExtensions.cssrc/Core/src/WindowExtensions.cssrc/Essentials/src/AssemblyInfo/AssemblyInfo.shared.cssrc/Essentials/src/Clipboard/Clipboard.shared.cssrc/Essentials/src/FilePicker/FilePicker.tizen.cssrc/Essentials/src/FileSystem/FileSystemUtils.android.cssrc/Essentials/src/FileSystem/FileSystemUtils.shared.cssrc/Essentials/src/MainThread/MainThread.netstandard.cssrc/Essentials/src/MainThread/MainThread.shared.cssrc/Essentials/src/MediaPicker/MediaPicker.ios.cssrc/Essentials/src/MediaPicker/MediaPicker.tizen.cssrc/Essentials/src/Types/Shared/WebUtils.shared.cssrc/Graphics/src/Graphics/Platforms/Android/PlatformGraphicsView.cssrc/Graphics/src/Graphics/Platforms/MaciOS/PlatformCanvas.cssrc/Graphics/src/Graphics/Platforms/Windows/PlatformGraphicsView.cssrc/Graphics/src/Graphics/Platforms/iOS/PlatformGraphicsView.cssrc/SingleProject/Resizetizer/src/GenerateTizenManifest.cssrc/SingleProject/Resizetizer/src/SkiaSharpSvgTools.cs
New files (not reverted):
src/Controls/src/Core/Handlers/Items/iOS/IScrollTrackingDelegator.cssrc/Controls/src/Core/Platform/AlertManager/DelegateAlertSubscription.cssrc/Core/src/Handlers/HybridWebView/HybridWebViewHelper.cssrc/Core/src/Platform/Android/AppbarLayoutExtensions.cssrc/Core/src/Platform/Android/IBackNavigationState.cssrc/Core/src/Platform/Android/RefreshViewWebViewScrollCapture.cssrc/Core/src/Platform/Windows/MauiLayoutAutomationPeer.cssrc/Core/src/Platform/iOS/MauiProgressView.cssrc/Core/src/Platform/iOS/MauiSwitch.cssrc/Core/src/ScreenshotDispatch.cs
🧪 UI Tests — ViewBaseTests
Detected UI test categories: ViewBaseTests
🔍 Pre-Flight — Context & Validation
Issue: #35257 - iOS 26 Switch default color for Off and On is incorrect + Off Color is not applied at start + Thumb Colors is not applied
PR: #35385 - [iOS] Fix Switch custom colors on iOS 26
Platforms Affected: iOS, MacCatalyst
Files Changed: 3 implementation, 2 test/sample
Key Findings
- The issue reports iOS 26+
Switchcustom colors rendering incorrectly: initial off colors are wrong andThumbColoris not applied. - The PR fixes this by selecting
UISwitchStyle.Slidingfor customized switches on iOS/MacCatalyst 26+, preservingAutomaticfor default switches, and reapplying colors after UIKit lifecycle/style resets. - Changed implementation files:
src/Core/src/Handlers/Switch/SwitchHandler.iOS.cs,src/Core/src/Platform/iOS/MauiSwitch.cs,src/Core/src/Platform/iOS/SwitchExtensions.cs. - Changed validation surfaces:
src/Core/tests/DeviceTests/Handlers/Switch/SwitchHandlerTests.iOS.csand HostApp registration. - Test type: Core device tests on iOS; impacted UI category: Switch.
Code Review Summary
Verdict: LGTM
Confidence: medium
Errors: 0 | Warnings: 0 | Suggestions: 0
Key code review findings:
- No blocking code-review findings were identified.
- Failure-mode probe: removing lifecycle reapply causes targeted Switch tests to fail, so style selection alone is insufficient.
- Blast radius: limited to iOS/MacCatalyst
Switchcolor updates; default switches are explicitly preserved asUISwitchStyle.Automaticwhen no MAUI custom colors are set.
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #35385 | Use iOS/MacCatalyst 26+ UISwitchStyle.Sliding for customized switches, preserve Automatic defaults, and queue lifecycle color reapply in MauiSwitch. |
Gate PASSED | 3 implementation, 2 test/sample | Original PR |
🔬 Code Review — Deep Analysis
Code Review - PR #35385
Independent Assessment
What this changes: The PR changes the iOS/MacCatalyst Switch handler/platform implementation so customized MAUI switch colors opt into UISwitchStyle.Sliding on iOS/MacCatalyst 26+, reapply track/thumb colors after UIKit rebuild/lifecycle events, and clear native custom color state when MAUI colors are reset to default.
Inferred motivation: UIKit's iOS 26 automatic/liquid switch style appears to ignore or overwrite MAUI TrackColor/ThumbColor customizations, especially during initial rendering and lifecycle/theme/window transitions.
Reconciliation with PR Narrative
Author claims: The PR fixes #35257 by using the public classic sliding switch style only when MAUI colors are customized, preserving automatic style for unstyled switches, reapplying colors after UIKit lifecycle/style resets, clearing ThumbTintColor on reset, and adding focused iOS handler coverage.
Agreement/disagreement: The implementation matches those claims. The tests cover style selection, default-style preservation, thumb reset, custom-color reset, moved-to-window reapply, and app theme/lifecycle color updates.
Findings
No blocking code-review findings were identified in the changed implementation.
Devil's Advocate
The main risk is complexity in MauiSwitch: it keeps a weak virtual-view reference, pending reapply state, and asynchronous main-queue retry logic. However, alternative candidates showed why this complexity exists: storing callbacks/events on NSObject subclasses violates MAUI memory analyzers, and removing the retry lifecycle path causes Switch regression tests to fail. The style change is also gated to iOS/MacCatalyst 26+ and only for customized colors, reducing blast radius for default switches.
Verdict: LGTM
Confidence: medium
Summary: The PR's approach is more robust than the explored alternatives because it handles delayed UIKit internal view readiness and lifecycle resets while preserving default switch behavior. The changed area is iOS/MacCatalyst Switch rendering only, with targeted device-test coverage.
🔧 Fix — Analysis & Comparison
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | try-fix-1 | Opportunistic MauiSwitch reapply from lifecycle callbacks without queued pending state. |
Fail | 1 file | Build succeeded, but the iOS device command exited with failed tests outside Switch, so it cannot be considered a passing candidate. Also weaker than PR for delayed UIKit resets. |
| 2 | try-fix-2 | Handler-owned color reapply callback; MauiSwitch only signals lifecycle readiness. |
Fail | 2 files | Rejected by MAUI NSObject memory analyzers (MEM0001, then MEM0002) because event/delegate callback storage on MauiSwitch can leak. |
| 3 | try-fix-3 | Minimal iOS 26 style selection and immediate reapply only; remove lifecycle retry machinery. | Fail | 3 files | Builds, but targeted iOS run failed 4 Switch tests, proving lifecycle reapply is needed. |
| PR | PR #35385 | UISwitchStyle.Sliding for customized switches on iOS/MacCatalyst 26+, default Automatic, queued lifecycle color reapply, and reset cleanup. |
Gate PASSED | 3 implementation, 2 test/sample | Original PR |
Cross-Pollination
| Model | Round | New Ideas? | Details |
|---|---|---|---|
| maui-expert-reviewer | 1 | Yes | Explore smaller lifecycle reapply, handler-owned callback, and minimal style-only variants. |
| local test loop | 1 | No | Candidate failures showed handler callbacks conflict with NSObject memory analyzers and style-only fix misses lifecycle-reset regressions. Candidate 1 was not demonstrably better and did not produce a clean test run. |
Exhausted: Yes
Selected Fix: PR #35385 - No alternative candidate passed all tests and was demonstrably better. Candidate 1 was smaller but did not produce a clean device-test run and weakens delayed retry behavior; candidate 2 fails analyzers; candidate 3 fails Switch regression tests. The PR fix remains the most robust option.
📋 Report — Final Recommendation
Comparative Fix Report - PR #35385
Candidates compared
| Candidate | Regression result | Assessment | Rank |
|---|---|---|---|
pr |
Passed | Existing PR fix. Gate passed: tests fail without the fix and pass with the fix. Expert review found no actionable correctness, safety, or performance issues. | 1 |
pr-plus-reviewer |
Passed | Same implementation as pr; expert reviewer had no changes to apply, so this candidate is equivalent to the PR fix. |
1 |
try-fix-1 |
Failed | Opportunistic MauiSwitch color reapply from lifecycle callbacks without the PR's queued pending state. Build succeeded, but the iOS device run exited TESTS_FAILED; it also weakens the PR's delayed UIKit-reset retry guarantee. |
3 |
try-fix-2 |
Failed | Handler-owned color reapply callback with MauiSwitch as a lifecycle signal source. Rejected by MAUI NSObject memory analyzers (MEM0001, then MEM0002) because event/delegate callback storage on MauiSwitch can leak. |
4 |
try-fix-3 |
Failed | Minimal iOS 26 style selection plus immediate reapply only, removing lifecycle retry machinery. Targeted iOS run failed 4 Switch tests, proving style selection alone is not enough. | 5 |
Winner
Winner: pr
The raw PR fix is selected because the required gate passed and the MAUI expert reviewer found no actionable issues. pr-plus-reviewer is functionally identical because there was no reviewer feedback to apply, so choosing pr avoids inventing a separate modified candidate.
Rationale
Candidates that failed regression tests are ranked below candidates that passed them. try-fix-1 did not produce a clean iOS test run and is less robust around delayed UIKit resets; try-fix-2 fails memory analyzers; and try-fix-3 fails targeted Switch regression coverage. The PR fix passed the gate and expert review found no actionable issue, so the submitted PR remains the single winning candidate.
Description of Change
Fixes iOS 26
Switchcustom color rendering by using UIKit's public classic sliding switch style when MAUI switch colors are customized.On iOS 26, the automatic/liquid
UISwitchstyle can ignore MAUIOffColor/OnColortrack tinting andThumbColor. This change opts switches with a non-null MAUI track or thumb color intoUISwitchStyle.Slidingon iOS 26+, while leaving unstyled switches asUISwitchStyle.Automaticto preserve the native default appearance.This also:
ThumbTintColorwhenThumbColoris reset tonull.Issue35257Appium visual regression coverage from [iOS 26] Fix Switch ThumbColor and OffColor not applied on initial load #35400 and adds focused iOS handler tests for the style, reset, theme-change, and reattachment paths.Conflict resolution:
inflight/current.Issue35257HostApp page, Appium test, andIssue35257_*snapshots as the source of truth for visual coverage.SwitchCustomColorsRenderOnInitialStatesnapshot/test shape during conflict resolution.Validation performed:
dotnet build src/Core/src/Core.csproj -f net10.0-ios26.0 -c Debug --no-restoredotnet build src/Controls/tests/TestCases.iOS.Tests/Controls.TestCases.iOS.Tests.csproj -c Debug --no-restoreIssues Fixed
Fixes #35257