-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Fixed Switch Thumb and On Colors #20346
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Hey there @kubaflo! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed. |
850ee01 to
627ee31
Compare
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
|
Any reason this has been sitting unmerged for a month? Seems like a pretty basic and critical bug to be sitting unfixed for months now |
|
/azp run MAUI-UITests-public |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
@jsuarezruiz @rmarinho |
|
@MAUIoxo we are not sure this is correct fix to work with VSM. we were discussing internally. |
|
Thanks for the update on this! So, at least we know why it is parked 😊 |
Hi, was the discussion effective ? |
Yes it was - I found out that this issue is going to take forever to be fixed and probably no one is going to deal with a solution anytime soon, so I guess I'll just have to come up with my own solution 😅 Here is an example of a CustomSwitch: namespace OptimizerApp.Pages.Views.Controls.CustomSwitch
{
public class CustomSwitch : Switch
{
}
}Integration in XAML Code: ...
<constrols:CustomSwitch ... IsToggled="{Binding IsSelected, Mode=TwoWay}" ThumbColor="{StaticResource Gray100}" OnColor="{StaticResource DarkOrange1}" />
...CustomSwitchHandler: #if IOS
using OptimizerApp.Pages.Views.Controls.CustomSwitch;
using Microsoft.Maui.Handlers;
using Microsoft.Maui.Platform;
using UIKit;
namespace OptimizerApp.Platforms.iOS.ControlHandlers
{
public partial class CustomSwitchHandler : ViewHandler<CustomSwitch, UISwitch>
{
/// <summary>
/// Configures property mappings for the CustomSwitch and binds UI properties to platform-specific handlers.
/// This mapper directs changes in MAUI's CustomSwitch properties to appropriate methods that
/// update the native iOS UISwitch, ensuring UI consistency and responsiveness:
/// - 'IsToggled' updates the switch's active state.
/// - 'OnColor' adjusts the color when the switch is on.
/// - 'ThumbColor' changes the color of the switch thumb.
/// These mappings ensure that the visual state of the UISwitch is synchronized with the CustomSwitch.
/// </summary>
public static PropertyMapper<CustomSwitch, CustomSwitchHandler> CustomSwitchMapper = new PropertyMapper<CustomSwitch, CustomSwitchHandler>
{
[nameof(CustomSwitch.IsToggled)] = MapIsToggled,
[nameof(CustomSwitch.OnColor)] = MapOnColor,
[nameof(CustomSwitch.ThumbColor)] = MapThumbColor
};
public CustomSwitchHandler() : base(CustomSwitchMapper)
{
}
/// <summary>
/// Creates the native UISwitch view
/// </summary>
/// <returns>The newly created UISwitch instance</returns>
protected override UISwitch CreatePlatformView()
{
return new UISwitch();
}
/// <summary>
/// Connects this handler to the UISwitch, setting up event handlers and initial state
/// </summary>
/// <param name="platformView">The UISwitch to connect</param>
protected override void ConnectHandler(UISwitch platformView)
{
base.ConnectHandler(platformView);
platformView.ValueChanged += OnSwitchValueChanged;
platformView.On = VirtualView.IsToggled; // Synchronize the UISwitch's state with the IsToggled property of the MAUI CustomSwitch
SetSwitchColors(platformView, VirtualView);
}
/// <summary>
/// Disconnects this handler from the UISwitch and clean up the event handlers
/// </summary>
/// <param name="platformView">The UISwitch to disconnect</param>
protected override void DisconnectHandler(UISwitch platformView)
{
platformView.ValueChanged -= OnSwitchValueChanged;
base.DisconnectHandler(platformView);
// Reset UI properties
ResetSwitchColors(platformView);
}
/// <summary>
/// Sets the ThumbColor and OnTintColor of the UISwitch based on the properties of the CustomSwitch
/// </summary>
/// <param name="uiSwitch">The native UISwitch</param>
/// <param name="customSwitch">The MAUI CustomSwitch</param>
private static void SetSwitchColors(UISwitch uiSwitch, CustomSwitch customSwitch)
{
// Setting the null-values will set it to default values
uiSwitch.ThumbTintColor = customSwitch.ThumbColor != default(Color) ? customSwitch.ThumbColor.ToPlatform() : null;
uiSwitch.OnTintColor = customSwitch.OnColor != default(Color) ? customSwitch.OnColor.ToPlatform() : null;
}
/// <summary>
/// Resets the ThumbColor and OnTintColor properties of the UISwitch to defaults
/// </summary>
/// <param name="uiSwitch">The UISwitch to reset</param>
private void ResetSwitchColors(UISwitch uiSwitch)
{
uiSwitch.ThumbTintColor = null;
uiSwitch.OnTintColor = null;
}
/// <summary>
/// Map changes in the OnColor property to the UISwitch
/// </summary>
public static void MapOnColor(CustomSwitchHandler handler, CustomSwitch customSwitch)
{
if (handler.PlatformView != null)
{
handler.PlatformView.OnTintColor = customSwitch.OnColor.ToPlatform();
}
}
/// <summary>
/// Map changes in the ThumbColor property to the UISwitch
/// </summary>
public static void MapThumbColor(CustomSwitchHandler handler, CustomSwitch customSwitch)
{
if (handler.PlatformView != null)
{
handler.PlatformView.ThumbTintColor = customSwitch.ThumbColor.ToPlatform();
}
}
/// <summary>
/// Map changes in the IsToggled property to the UISwitch
/// </summary>
public static void MapIsToggled(CustomSwitchHandler handler, CustomSwitch customSwitch)
{
if (handler.PlatformView != null)
{
handler.PlatformView.On = customSwitch.IsToggled;
handler.UpdateSwitchColors(handler.PlatformView, customSwitch); // Update colors when switch is toggled/untoggled
}
}
private void OnSwitchValueChanged(object sender, EventArgs e)
{
var uiSwitch = (UISwitch)sender;
VirtualView.IsToggled = uiSwitch.On;
UpdateSwitchColors(uiSwitch, VirtualView);
}
/// <summary>
/// Update the OnTintColor and ThumbColor with the colors defined in the customSwitch
/// </summary>
private void UpdateSwitchColors(UISwitch uiSwitch, CustomSwitch customSwitch)
{
if (uiSwitch.On)
{
if (customSwitch.OnColor != default(Color))
{
uiSwitch.OnTintColor = customSwitch.OnColor.ToPlatform();
}
}
if (customSwitch.ThumbColor != default(Color))
{
uiSwitch.ThumbTintColor = customSwitch.ThumbColor.ToPlatform();
}
}
}
}
#endifMauiProgram.cs: ...
#if IOS
using OptimizerApp.Platforms.iOS.ControlHandlers;
#endif
...
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
...
.ConfigureMauiHandlers(handlers =>
{
// The handler will only be called if the target platform is iOS
#if IOS
handlers.AddHandler<CustomSwitch, CustomSwitchHandler>();
#endif
});
...BUT: Simple Switch iOS: CustomSwitch iOS: Simple Switch Android: CustomSwitch Android: |
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
|
For me the simplest solution was to go into Resources/Styles/Styles.xaml, search for "Switch" and set colors you need both for dark and white theme. |
|
I have tried this, but its not working. ThumbColor not getting changed even if set using DataTrigger. Screen.Recording.2024-08-14.at.11.01.17.PM.mov |
|
464b341 to
e2ebe3a
Compare
|
@jsuarezruiz could you please /azp @divyesh008 can you please try again with changes I've just added |
|
/rebase |
e2ebe3a to
9fb6ad9
Compare
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
9fb6ad9 to
597f6bc
Compare
It's the anniversary of your comment 😂 |
The 7th year is always the critical one 😅😂 |
mattleibow
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Picking option red because I wonder if this is fixed or requires a different fix to work with the style specificities.
Also, could the "not working" be the case because the is no Normal style to fall back to?
| public static readonly BindableProperty ThumbColorProperty = BindableProperty.Create(nameof(ThumbColor), typeof(Color), typeof(Switch), null, | ||
| propertyChanged: (bindable, oldValue, newValue) => | ||
| { | ||
| ((IView)bindable)?.Handler?.UpdateValue(nameof(ISwitch.ThumbColor)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
didn't this property automatically fire this update?
| ((IView)bindable)?.Handler?.UpdateValue(nameof(ISwitch.TrackColor)); | ||
|
|
||
| ((IView)bindable)?.Handler?.UpdateValue(nameof(ISwitch.ThumbColor)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe with the new work @StephaneDelcroix did with style specificities, this is no longer needed and the style should swap?
|
/rebase |
597f6bc to
242b708
Compare
|
@mattleibow you're right. The changes are no longer needed, so I'm closing this PR |





Description of Change
The initial respect for the ThumbColor and OnColor properties was
overridden by values set within visual states each time the switcher changed
its state. I recommend verifying whether these values have been overwritten,
and if so, exclusively utilizing the new properties.
Issues Fixed
Fixes #19883
Fixes #19380
Simulator.Screen.Recording.-.iPhone.15.Pro.Max.-.2024-02-03.at.02.06.58.mp4
Screen.Recording.2024-02-04.at.00.25.46.mov