Forum Xamarin.Forms
We are excited to announce that the Xamarin Forums are moving to the new Microsoft Q&A experience. Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

We encourage you to head over to Microsoft Q&A for .NET for posting new questions and get involved today.

How not to change the state of the switch when pressed

lucagtolucagto Member ✭✭

On iOS I need not to change the state of the switch when pressed,
I would like to change its state only using the command

switch.IsToggled = true

I would like switcth.Toggled + = ...to call a function but not to affect the state of the switch

Does anyone know how to do it?
Many thanks.

Best Answer

Answers

  • PaulNTUPaulNTU USMember ✭✭✭

    Would setting the enabled state for the control to false work for this?

  • JohnHardmanJohnHardman GBUniversity admin
    edited March 2019

    @lucagto said:
    I would like switcth.Toggled + = ...to call a function but not to affect the state of the switch

    You want this event fired when the Switch is changed programmatically only, or also when the user taps on the Switch?

    @lucagto said:
    On iOS I need not to change the state of the switch when pressed,
    I would like to change its state only using the command

    switch.IsToggled = true

    I would like switcth.Toggled + = ...to call a function but not to affect the state of the switch

    Do you want the Switch to appear disabled?

    Depending on your answers to the above 2 questions, you might simply want to set IsEnabled=false, or you might want to overlay a transparent BoxView on top of the Switch, using the BoxView's InputTransparent as required to prevent clicks etc reaching the Switch, and setting the Switch's IsTabStop to false to prevent the user tabbing to the Switch.

    Be aware that having a Switch that appears Enabled, but that does not operate as the users would expect, is going to confuse the users.

  • lucagtolucagto Member ✭✭

    @PaulNTU said:
    Would setting the enabled state for the control to false work for this?

    if I use > sblue.IsEnabled = false I can't press on it anymore, I want to be able to press the switch but I don't want it to change its state

  • lucagtolucagto Member ✭✭
    edited March 2019

    @JohnHardman

    I want the event to active just with user pressure, I don't want the switch to appear disabled.

    I want the user to be able to press the switch to activate the function but the switch must not change its state in pressure, but only by code.

  • PaulNTUPaulNTU USMember ✭✭✭

    Once it is toggled by the user can you not set its switch.IsToggled state to return it back to its pre pressed state again

  • lucagtolucagto Member ✭✭

    @PaulNTU said:
    Once it is toggled by the user can you not set its switch.IsToggled state to return it back to its pre pressed state again

    No because the animation would be seen anyway

  • RHudsonRHudson CAMember ✭✭✭

    Curiosity got the better of me. Why in the world do you want to do this?

    Perhaps there is a better UI solution.

  • lucagtolucagto Member ✭✭

    @RHudson said:
    Curiosity got the better of me. Why in the world do you want to do this?

    Perhaps there is a better UI solution.

    This switch I need to activate or deactivate the bluetooth, on iOS it is not possible to change the bluetooth status without going through the ios settings window, so when a user presses on the switch the ios bluetooth settings will open, after setting bluetooth the user returns to the application and the status of the switch is updated with the bluetooth status, which is why I want no animation to occur at the pressure on the switch.
    I hope I was clear.

  • RHudsonRHudson CAMember ✭✭✭

    @lucatgo

    Yes, it's clear what you want to accomplish. But I think this is a poor UI design, no offense.

    It's an unexpected behavior and will confuse the users.
    When you tap a switch the expected behavior is to have the switch simply slide over. Nothing else. Certainly not open a dialog.

    What I would do is have a button "Turn on BlueTooth" which then launches your settings dialog.

    The user will understand this better.

    Besides.... even if you decide to use a switch, why can't you simply bind it to a flag in your VM which then kicks off your dialog code.
    Why the smoke-and-mirrors?

  • lucagtolucagto Member ✭✭

    @RHudson

    I'm not the one who decides the graphic interface of the application, I was told to do so and so I have to do.
    It's a code shared with android, on andorid the switch is able to disable the bluetooth without going in the settings, probably they want to get a coherent interface between the two operating systems.

  • lucagtolucagto Member ✭✭

    @PaulNTU

    Ok so it works, it's not elegant because I would have preferred to overwrite the behavior of the switch on ios, but that's fine.

    Now I'm trying to update the status of the switch after setting it from the ios settings, I'm using the OnAppearing () function, but it's not working.

    Frame f = this.FindByName("click") as Frame;
    
    if (Device.RuntimePlatform == Device.Android)
    {
            sblue.Toggled += Change_Status_Bluetooth;
    }
    else
    {
         TapGestureRecognizer tap = new TapGestureRecognizer();
             sblue.InputTransparent = true;
             tap.Tapped += Change_Status_BluetoothIOS;
             f.GestureRecognizers.Add(tap);
    }
    
             sblue.IsToggled = Utils.BluetoothIsActive();
    
    ...
    
    private void Change_Status_BluetoothIOS(object sender, EventArgs e)
            {
                if (firstAccess)
                {
                    var t = Task.Run(() =>
                    {
                        Device.BeginInvokeOnMainThread(() =>
                        {
                            Utils.ChangeStateBluetooth();
    
                        });
                    });
                }
            }
    
     protected override void OnAppearing()
    {
        sblue.IsToggled = Utils.BluetoothIsActive();
    }
    

    Some advice?

    thanks a lot

  • JohnHardmanJohnHardman GBUniversity admin

    @lucagto said:
    but it's not working.

    Clarify "it's not working". What happens? What do you expect to happen? Have you added breakpoints and/or traced through the code to see which code gets executed?

  • RHudsonRHudson CAMember ✭✭✭
    edited March 2019

    @lucatgo Can you not do something like this?

           bool _bluetoothState;
            public bool BlueToothState
            {
                get  { return _bluetoothState; }
    
                set
                {
                    if (firstAccess)
                    {
                        var t = Task.Run(() =>
                        {
                            Device.BeginInvokeOnMainThread(() =>
                            {
                                Utils.ChangeStateBluetooth();
    
                            });
                        });
                    }
                }
            }
    
            protected override void OnAppearing()
            {
                _bluetoothState = Utils.BluetoothIsActive();
            }
    
    

    And bind your switch to BluetoothState ?

  • lucagtolucagto Member ✭✭

    @JohnHardman said:

    @lucagto said:
    but it's not working.

    Clarify "it's not working". What happens? What do you expect to happen? Have you added breakpoints and/or traced through the code to see which code gets executed?

    When I press on the switch opens the ios bluetooth settings, when I go back to my app the status of the switch is not updated compared to what I set in the bluetooth settings

    Execution passes from the onappearing function but the status of the switch does not update.

  • lucagtolucagto Member ✭✭

    @RHudson

    It looks very similar to what I'm doing, I don't understand how it can update the status of the switch like that, I'm sorry but I'm new to Xamarin and C #.

  • lucagtolucagto Member ✭✭

    I should probably useOnResume(), but I'm not understanding how to do it.

  • RHudsonRHudson CAMember ✭✭✭
    edited March 2019

    @lucagto said:
    @RHudson

    It looks very similar to what I'm doing, I don't understand how it can update the status of the switch like that, I'm sorry but I'm new to Xamarin and C #.

    @lucagto When the user taps the switch, the code in the Set {} will fire.

    You don't need to worry about updating the status of the switch. That's what MVVM and binding is all about. The switch will look after itself.

    Have a look at some MVVM basics, perhaps
    https://docs.microsoft.com/en-us/xamarin/xamarin-forms/xaml/xaml-basics/data-bindings-to-mvvm
    or
    https://docs.microsoft.com/en-us/xamarin/xamarin-forms/enterprise-application-patterns/mvvm
    or
    https://redpillxamarin.com/2017/01/08/401-revisiting-mvvm/

    @lucagto said:
    I should probably useOnResume(), but I'm not understanding how to do it.

    No no no no no no no no. Review those basics first.

    (Note to self... I need to change the cardinal's bubble caption. XF is actually very stable now, not like 4 years ago)

  • lucagtolucagto Member ✭✭

    @RHudson

    I read those guides, at the moment I can tell you that I don't understand how to use your function, I can't do switch.Toggled + = BlueToothState

  • JohnHardmanJohnHardman GBUniversity admin
    edited March 2019

    @lucagto said:
    When I press on the switch opens the ios bluetooth settings, when I go back to my app the status of the switch is not updated compared to what I set in the bluetooth settings

    Execution passes from the onappearing function but the status of the switch does not update.

    By "Execution passes from the onappearing function", you mean that OnAppearing is called and the line "sblue.IsToggled = Utils.BluetoothIsActive();" is executed in the scenario where control returns from the settings page to your app?

    Do you call base.OnAppearing() ? (you haven't posted your entire page class, so we don't know if you have a base page class that you use)

    The code that you posted does not show what sblue is, nor what Utils.BluetoothIsActive does. To identify the cause of the problem with certainty, we need that.

  • lucagtolucagto Member ✭✭

    For now I have solved in the following way: I used the frame as suggested above, I created a function that updates the switch that is called in the App.cs in the onResume, checking if they are in the correct page, otherwise onResume does not intervene.

    Thank you all for your help

Sign In or Register to comment.