How to make my RefreshControl appear during ViewDi

2019-07-27 13:08发布

问题:

I've answered this question myself - just leaving it here now for people with the same issue.

My code is fairly simple - A custom table with a datasource to provide data asynchronously from a web service.

In order to get the nicest user experience I would like to have the UIRefreshControl animate the process of loading whenever this controller appears, instead of just when the list has been pulled down.

Unfortunately the UIRefreshControl does not appear at all if I call my method during ViewDidAppear.

I've tried suggestions from answers these questions, but none of them seemed to work for me:

public partial class ControlCenterSelectionController : UITableViewController
{
    public ControlCenterSelectionController (IntPtr handle) : base (handle)
    {
    }

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

        TableView.RefreshControl = new UIRefreshControl();
        TableView.RefreshControl.ValueChanged += RefreshControlOnValueChanged;
    }

    private async void RefreshControlOnValueChanged(object sender, EventArgs eventArgs)
    {
        await UpdateDataSourceAsync();
    }

    public override async void ViewDidAppear(bool animated)
    {
        base.ViewDidAppear(animated);
        TableView.SetContentOffset(new CGPoint(0, -TableView.RefreshControl.Frame.Size.Height), true);
        await UpdateDataSourceAsync();
    }

    private async Task UpdateDataSourceAsync()
    {
        TableView.RefreshControl.BeginRefreshing();
        var ccClient = DI.Instance.Get<IControlCenterRestClient>();
        var controlCenters = await ccClient.GetAllAsync();
        var source = new GenericViewSource<ControlCenter>(controlCenters, item => item.Name, ControlCenterSelected);
        TableView.Source = source;
        TableView.RefreshControl.EndRefreshing();
    }

    private void ControlCenterSelected(ControlCenter controlCenter)
    {
        var controller = this.InstantiateController(Constants.ViewControllerIds.ControlCenter) as ControlCenterController;
        controller.ControlCenter = controlCenter;
        this.NavigateTo(controller);
    }
}
  • UITableView UIRefreshControl Does Not Show Its View The First Time
  • UIRefreshControl on viewDidLoad
  • UIRefreshControl - beginRefreshing not working when UITableViewController is inside UINavigationController

All I currently get is a screen which looks empty, loads data without indication and then updates the screen once it's done.

Can someone spot an error? I can't really find one, since this code is rather simple.

回答1:

The desperation of posting it on SO + desperate coding attempts were key:

    public override async void ViewDidAppear(bool animated)
    {
        base.ViewDidAppear(animated);
        TableView.SetContentOffset(new CGPoint(0, -(TableView.RefreshControl.Frame.Size.Height + 20)), true);
        TableView.RefreshControl.BeginRefreshing();
        await UpdateDataSourceAsync();
    }

    private async Task UpdateDataSourceAsync()
    {
        var ccClient = DI.Instance.Get<IControlCenterRestClient>();
        var controlCenters = await ccClient.GetAllAsync();
        var source = new GenericViewSource<ControlCenter>(controlCenters, item => item.Name, ControlCenterSelected);
        TableView.Source = source;
        TableView.RefreshControl.EndRefreshing();
    }

This change in particular made the difference:

-(TableView.RefreshControl.Frame.Size.Height + 20)

Turns out that, while in the other questions the issue was fixed by simply applying a scroll based on RefreshControl would fire the animation, in my case I had to add some extra y delta to make the animation fire.

Correction

this extra offset seems to be required only if extended edges is set to extend under top bars.