Forum Xamarin Xamarin.iOS

Top Visible Table Cell Not Updating After ReloadData Called

Jon.0578Jon.0578 USUniversity ✭✭

I am currently developing an application using MvvmCross and Xamarin iOS. The main view of the application is split into two. The lower half of the view is a table view.

The table view is populated by an async proses that works correctly.

If a user taps to select the item, they are navigated to another view that enables them to update the selected item. The update causes the data source to be reloaded (as the edit may have affected other items) and the table view to reload.

The table view is not in view during the reload process; however the reload is performed on the main thread.

In all cases this works correctly, apart from when the top visible row is selected. In this instance the cell is never updated. Each time it is selected for reuse the view renders with the initial data that it was created with.

From the console output I can see that prepare for reuse is being invoked on all of the cells. I can also confirm that the reload operation on the table is being invoked on the main thread.

The table data source (extended from MvxSimpleTableSource) does invoke the overload for GetOrCreateCellFor and the data for the bound items is updated. All of my investigations have not been able to resolve the issue.

Please can anyone help.

Best Answer

  • Jon.0578Jon.0578 USUniversity ✭✭
    Accepted Answer

    I have now resolved the issue bit would like to understand why it is happening.

    The issue seems to have been due to the oveload for the RowSelected method of the MvxSimpleTableSource.

    public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
    {
        try
        {
            if (!this.parent.ViewModel.IsLocked)
            {
                /*    Removing the following code enables the top visable cell to
                *     be reloaded correctly
                if (this.highlightedRow == null || this.highlightedRow.Row != indexPath.Row)
                {
                    var cell = this.GetCell(tableView, indexPath) as CustomTableCellWithImage;
                    if (cell != null)
                    {
                        cell.ContentView.BackgroundColor = this.parent.HighlightColor;
                     }
                }
                *     End of removed code
                */
                this.parent.ViewModel.SetNavigationDate();
                base.RowSelected(tableView, indexPath);
            }
        }
        catch (Exception ex)
        {
            this.parent.ViewModel.LogError(ex, "RowSelected indexPath: {0}", indexPath.ToString());
        }
    }  
    

    The bound command is async, and the code works for all selected rows unless it is the top visible row.

    When a user selects the top visible row the cell seems to get into a state where the view is never update, even when SetNeedsDisplay is directly invoked.

Answers

  • Jon.0578Jon.0578 USUniversity ✭✭
    Accepted Answer

    I have now resolved the issue bit would like to understand why it is happening.

    The issue seems to have been due to the oveload for the RowSelected method of the MvxSimpleTableSource.

    public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
    {
        try
        {
            if (!this.parent.ViewModel.IsLocked)
            {
                /*    Removing the following code enables the top visable cell to
                *     be reloaded correctly
                if (this.highlightedRow == null || this.highlightedRow.Row != indexPath.Row)
                {
                    var cell = this.GetCell(tableView, indexPath) as CustomTableCellWithImage;
                    if (cell != null)
                    {
                        cell.ContentView.BackgroundColor = this.parent.HighlightColor;
                     }
                }
                *     End of removed code
                */
                this.parent.ViewModel.SetNavigationDate();
                base.RowSelected(tableView, indexPath);
            }
        }
        catch (Exception ex)
        {
            this.parent.ViewModel.LogError(ex, "RowSelected indexPath: {0}", indexPath.ToString());
        }
    }  
    

    The bound command is async, and the code works for all selected rows unless it is the top visible row.

    When a user selects the top visible row the cell seems to get into a state where the view is never update, even when SetNeedsDisplay is directly invoked.

Sign In or Register to comment.