jsuarezruiz / AlohaKit.Controls

A set of .NET MAUI drawn controls.
MIT License
410 stars 46 forks source link

Issues with ToggleSwitch #57

Open davepruitt opened 1 year ago

davepruitt commented 1 year ago

I have encountered two issues with the ToggleSwitch control. I have also fixed them, and opened a pull request.

Here are the issues: (1) The ToggleSwitch still reacts to user interactions even if disabled (on Android). (2) The ToggleSwitch, upon initialization, does not accurately reflect its IsOn state.

More in depth about issue one:

Regarding the first issue, I have tested this on Windows 10 and Android 13 (using a Samsung Galaxy Tab A7 Lite). It seems that on Windows, setting the IsEnabled property works just fine. If IsEnabled is false, then interacting with the ToggleSwitch control will do nothing (as expected). This is not the case for Android. Even if IsEnabled is false, if I click on the ToggleSwitch, it will respond as if it is enabled.

I fixed this by simply adding an if-statement inside of OnToggleSwitchStartInteraction to check if the control is enabled/disabled:

void OnToggleSwitchStartInteraction(object sender, TouchEventArgs e)
{
    if (IsEnabled)
    {
        IsOn = !IsOn;
        AnimateToggle();    
    }
}

This seems to have the desired effect.

More in depth about issue two:

It seems that if I initialize the IsOn value to true, this is not reflected in the visual appearance of the ToggleSwitch. After doing a bit of debugging, it looks like the IsOn property is working fine - nothing is wrong with it. The problem is actually related to the ToggleSwitchDrawable class. ToggleSwitchDrawable has a property called AnimationPercent. This property is only ever set if the AnimateToggle function on ToggleSwitch is called. Unfortunately, AnimateToggle is never called when the ToggleSwitch is first initialized, and so AnimationPercent will remain 0. This means that the ToggleSwitchDrawable will appear off, even if IsOn is initialized to true.

Currently AnimateToggle is only ever called inside of OnToggleSwitchStartInteraction. If, however, we move this function call to be inside of UpdateIsOn, then it will be called any time IsOn is changed, even upon initialization of the ToggleSwitch. So, to fix this issue, I have removed the call to AnimateToggle from OnToggleSwitchStartInteraction, and I have put it in UpdateIsOn. So the code now looks like this (also incorporating the changes from the first issue in this post):

void UpdateIsOn()
{
    if (ToggleSwitchDrawable == null)
        return;

    ToggleSwitchDrawable.IsOn = IsOn;
    Toggled?.Invoke(this, new ToggledEventArgs(IsOn));

    Invalidate();

    AnimateToggle();
}

void OnToggleSwitchStartInteraction(object sender, TouchEventArgs e)
{
    if (IsEnabled)
    {
        IsOn = !IsOn;
    }
}

This seems to fix the issue, as far as I can tell.

I have fixed the issues and submitted a pull request: https://github.com/jsuarezruiz/AlohaKit.Controls/pull/56