1
votes

Hi Xamarin/MvvmCross devs,

This is just a question out of curiosity. In one of the apps I'm developing some behaviour changed. Specifically on iOS when binding the UISwitch "On" value to a boolean in the ViewModel. The getter on the property fires when the binding is applied as well as the setter when the switch is flipped, but the UI does not reflect it. Forcing me to go from just

var set = this.CreateBindingSet<SettingsView, SettingsViewModel>();
set.Bind(PushNotificationSwitch).For(s => s.On)
   .To(vm => vm.ReceivePushNotifications);
set.Apply();

To having to also add the following below that (to get the UI of the switch to reflect the value)

var settingsViewModel = ((SettingsViewModel)ViewModel);
PushNotificationSwitch.On = settingsViewModel.ReceivePushNotifications;

I left the binding, as well as the new code to reflect UI state, because in addition to the UI just reflecting the correct state, I also want it to change the state in my settingsService when the user changes it.

I recently upgraded through Xamarin Studio on Mac and my iOS Xam version is Version: 10.0.0.6. Unfortunately I didn't check what version I upgraded from, but I always upgrade as soon as I see there's one available, so it should be the previous stable version.

My questions are:

  • Has any of you experienced similar issues where bindings changed in this way?
  • Since the Android binding still works fine, do you think it's an issue in MvvmCross, or iOS Xamarin Changes
  • Any speculations as to what could be causing this? And other parts that you think this might affect, so I won't have to go scour for bugs if none exists. Commands, text and custom control bindings are working fine (as far as I've tested)

If this question would be better suited somewhere else please let me know, I'm just curious about this behaviour.

Thanks

1
Does this behavior shown on both debug and release builds or just one of them? It could be the linker which is stripping away code. Do you have any code in your LinkerPleaseInclude file for switches? - Cheesebaron
@Cheesebaron This happens for both debug and release, and I don't have any code for switches in my LinkerPleaseInclude file. - Filled Stacks
Can you try adding: public void Include(UISwitch sw) { sw.On = !sw.On; sw.ValueChanged += (sender, args) => { sw.On = false; }; } - Cheesebaron
@Cheesebaron that worked :) Looked through the logs after adding that in and saw that the upgrade of MvvmCross a three weeks back removed that, I only got back to the project recently so in my head it was related to the Xamarin Upgrade. My bad for Not checking properly. Thank you. - Filled Stacks
Did that help?? - Cheesebaron

1 Answers

3
votes

As we worked out in the comments of the OP the event of the switch was linked out. Hence, the binding did nothing.

Easiest way to remedy this is to add the following code to your LinkerPleaseInclude.cs file, which MvvmCross provides in the Startup NuGet and through the templates available for Visual Studio and Xamarin Studio:

public void Include(UISwitch sw) 
{ 
    sw.On = !sw.On;
    sw.ValueChanged += (sender, args) => 
    { 
        sw.On = false; 
    }; 
}

This will tell the Linker that there is a direct usage of both the ValueChanged event and the On property, since the LinkerPleaseInclude class uses the Preserve attribute.