Abel
Abel

Reputation: 315

Setting UITableView FooterView after table reloading

I'm making an app that as a UITableView that gets content from the web, parses it and shows it. It takes a little time to get it and parse it, so I use a loading indicator (MBProgressHUD) and do the loading in background. I wanted to add a button at the footer of the TableView, so I made up this code:

UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[myButton addTarget:self action:@selector(myAction)
   forControlEvents:UIControlEventTouchDown];
[myButton setTitle:@"Button Title" forState:UIControlStateNormal];
myButton.frame = CGRectMake(0, 0, 160.0, 40.0);
self.tableView.tableFooterView=myButton;

The proble is that it is initialized in the tableview during the ViewDidLoad() just after my background content loading code

MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
    hud.mode = MBProgressHUDModeIndeterminate;
    hud.labelText = @"Loading";
    dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
        // Do something...
        [self getContent];
        [self.tableView reloadData];
        dispatch_async(dispatch_get_main_queue(), ^{
            [MBProgressHUD hideHUDForView:self.view animated:YES];
        });
    }); 

So when the view loads, the button is set on top (since the tableview is empty) and when it reloads, the button stays on top, I need to go to another view and come back to have the button in the footer.

Is there a way to set the button after the content loading ? Like a -(void)tableViewDidReloadData function ?

Thanks !

Upvotes: 1

Views: 1886

Answers (3)

runmad
runmad

Reputation: 14886

Yes, if you do it in the same call as [self.tableView reloadData] (which is a synchronous call) it'll display once the data is loaded.

MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.mode = MBProgressHUDModeIndeterminate;
hud.labelText = @"Loading";
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
    // Do something...
    [self getContent];
    dispatch_async(dispatch_get_main_queue(), ^{
        [MBProgressHUD hideHUDForView:self.view animated:YES];
        [self.tableView reloadData];
        UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        [myButton addTarget:self action:@selector(myAction) forControlEvents:UIControlEventTouchDown];
        [myButton setTitle:@"Button Title" forState:UIControlStateNormal];
        [myButton setFrame:CGRectMake(0, 0, 160.0, 40.0)];
        [self.tableView setTableFooterView:myButton];
    });
});

Upvotes: 1

Piyush Kashyap
Piyush Kashyap

Reputation: 1965

Don't create myButton and assign it to tableview footer in ViewDidLoad delegate instead of this create it at the time when you are hiding the MBProgress HUD and reloading the table

Try this it should work

dispatch_async(dispatch_get_main_queue(), ^{
        UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        [myButton addTarget:self action:@selector(myAction)
        forControlEvents:UIControlEventTouchDown];
        [myButton setTitle:@"Button Title" forState:UIControlStateNormal];
        myButton.frame = CGRectMake(0, 0, 160.0, 40.0);
        self.tableView.tableFooterView=myButton;
        [self.tableView reloadData];
        [MBProgressHUD hideHUDForView:self.view animated:YES];
    });

Upvotes: 0

graver
graver

Reputation: 15213

You should call [self.tableView reloadData]; only in the main thread.

dispatch_async(dispatch_get_main_queue(), ^{
        [self.tableView reloadData];
        [MBProgressHUD hideHUDForView:self.view animated:YES];
    });

Upvotes: 0

Related Questions