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
Fixed Switch Thumb and On Colors #20346
base: main
Are you sure you want to change the base?
Conversation
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.
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();
}
}
}
}
#endif MauiProgram.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: |
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