Search code examples
iosxamarin.iosmvvmcross

MVVMCross iOS reselect table row after table refresh


Does anyone know how to make an iOS table view visually re-select a row after the table is refreshed?

Here is my current implementation:

MainView

public override void ViewDidLoad()
{
    base.ViewDidLoad();

    var source = new MvxSimpleTableViewSource(MainTableView, MainInspectionCell.Key, MainInspectionCell.Key);
    MainTableView.Source = source;
    var set = this.CreateBindingSet<MainView, MainViewModel>();
    set.Bind(source).To(vm => vm.Inspections);
    set.Bind(source).For(s => s.SelectionChangedCommand).To(vm => vm.ItemSelectedCommand);
    set.Bind(source).For(s => s.SelectedItem).To(vm => vm.SelectedInspection);
....
    set.Apply();

    MainTableView.ReloadData();
}

MainViewModel

I have a message that gets sent out when the syncing is complete and handled like so:

private async void OnSyncUpdate(UpdatedInspectionsMessage message)
{
    var updatedInspections = await inspectionManager.GetInspectionsAsync(cancellationToken);
    Inspections = new ObservableCollection<Inspection>(updatedInspections);
    ItemSelectedCommand.Execute(SelectedItem);
}

The idea here being.. when a sync is complete and my table refreshes to do a row select and re-highlight the item that I had selected. What happens right now is that my selected row is grey before refresh. After refresh my SelectedItem is still filled in but the row is no longer grey.

Any ideas?


Solution

  • So I got this to work by publishing a new message. I wonder if there is a cleaner way to do this but this works for me.

    When I complete my refresh in my ViewModel I do a:

    InvokeOnMainThread(async () =>
    {
        await Task.Delay(250, cancellationToken);
        ItemSelectedCommand.Execute(newSelected);
        messenger.Publish(new DoneUpdatingInspectionsMessage(this));
    });
    

    Then in my iOS view I have subscribed to a DoneUpdatingInspectionsMessage which does this:

    var path = NSIndexPath.FromRowSection(MainViewModel.Inspections.IndexOf(MainViewModel.SelectedInspection), 0);
    MainTableView.SelectRow(path, true, UITableViewScrollPosition.None);
    

    Note: I needed to build in a Delay because it was firing before my loading indicator would go away, which caused the row to not show as selected.