Search code examples
xamarinxamarin.iosuirefreshcontrol

Xamarin iOS RefreshControl is stuck


I have a problem with RefreshControl... I have this code:

In ViewDidLoad() I call method InitializeRefreshControl();

private void InitializeRefreshControl()
    {
        if (UIDevice.CurrentDevice.CheckSystemVersion(6, 0))
        {
            //UIRefreshControl iOS6
            ordersCollectionView.RefreshControl = new UIRefreshControl();
            ordersCollectionView.RefreshControl.AttributedTitle = new NSAttributedString("Pull To Refresh",
            new UIStringAttributes()
            {
                ForegroundColor = UIColor.Red,
                KerningAdjustment = 3
             });
            ordersCollectionView.RefreshControl.ValueChanged += HandleValueChanged;
        }
        else
        {
            // old style refresh button and no PassKit for older iOS
            NavigationItem.SetRightBarButtonItem(new UIBarButtonItem(UIBarButtonSystemItem.Refresh), false);
            NavigationItem.RightBarButtonItem.Clicked += (sender, e) => { Refresh(); };
        }
    }

HandleValueChange method and Refresh merhod is here:

private void HandleValueChanged(object sender, EventArgs e)
    {
        ordersCollectionView.RefreshControl.BeginRefreshing();
        ordersCollectionView.RefreshControl.AttributedTitle = new NSAttributedString("Refreshing",
            new UIStringAttributes()
            {
                ForegroundColor = UIColor.Blue,
                KerningAdjustment = 5
            });

        Refresh();
        ordersCollectionView.RefreshControl.EndRefreshing();
    }

    private void Refresh()
    {
        var viewModel = (OrdersViewModel)DataContext;
        viewModel.OnReloadData();
    }

My problem is when I pull down collectionVIew so Refresh loading is displayed but is stuck no loading effect and still with text "Pull to refresh". When method Refresh end so for 0,1ms is showing loading effect and text "Refreshing" but not before method Refresh... Someone know how solve this problem? Thanks for answer.


Solution

  • It looks like the issue is related to the Refresh(); method being synchronous. You'll need to make this operation happen in the background so that the UI thread is free to provide the animation for the RefreshControl. For example:

    private async void HandleValueChanged(object sender, EventArgs e)
    {
        ordersCollectionView.RefreshControl.BeginRefreshing();
        ordersCollectionView.RefreshControl.AttributedTitle = new NSAttributedString("Refreshing",
            new UIStringAttributes()
            {
                ForegroundColor = UIColor.Blue,
                KerningAdjustment = 5
            });
    
        // await a Task so that operation is done in the background
        await Refresh();
        ordersCollectionView.RefreshControl.EndRefreshing();
    }
    
    // Marked async and Task returning
    private async Task Refresh()
    {
        var viewModel = (OrdersViewModel)DataContext;
        // Need to update this method to be a Task returning, async method.
        await viewModel.OnReloadData();
    }
    

    The above code refactors what you had to use async/await and Tasks. You may need to refactor some more of your code to make that work, including the OnReloadData() method.

    There are lots of resources for getting started with Tasks, async and await. I can start you off with this reference from the Xamarin blog.