0

I have a tableView and need to perform a function once the tableView has been reloaded. How do I know if reloadData has finished? Lets say I have methodA that populates the tableView, and once [tableView1 reloadData] has been completed, I want to call methodB. Can anyone help me with this? I've been searching for hours... Thank you!

- (void) methodA
{

    NSString *URLa = [NSString stringWithFormat:@"http://www.website.com/page.php?
    v1=%@&v2=%@&v3=%@",v1, v2, v3];

    NSURL *url = [NSURL URLa];

    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    (void) [[NSURLConnection alloc] initWithRequest:request delegate:self];

    [tableView1 reloadData];

}
Anoop Vaidya
  • 46,283
  • 15
  • 111
  • 140
Brandon
  • 2,163
  • 6
  • 40
  • 64
  • 1
    http://stackoverflow.com/questions/4163579/how-to-detect-the-end-of-loading-of-uitableview – Anil Kothari Mar 05 '13 at 08:21
  • Thanks @Anil - Ive actually tried this, but need the method to fire even if there are no results returned. Actually, I need it to fire ONLY if no results are returned. The answer in that post won't fire if the tableView is empty. – Brandon Mar 05 '13 at 08:23
  • Note that `initWithRequest` only starts an asynchroneous operation. You should call `reloadData` in `connectionDidFinishLoading` - and then you know if there are results or not! – Martin R Mar 05 '13 at 09:05
  • Am I missing something? `reloadData` is synchronous, isn't it? – Carl Veazey Mar 05 '13 at 09:13
  • @CarlVeazey: Yes, that's why I do not understand the answer. – Martin R Mar 05 '13 at 09:18
  • http://stackoverflow.com/questions/9675667/is-uitableview-reloaddata-asynchronous-or-synchronous – Anoop Vaidya Mar 05 '13 at 09:20
  • @AnoopVaidya sure enough... I was running an insufficient experiment.... – Carl Veazey Mar 05 '13 at 09:25
  • @CarlVeazey: should I change the block name? I didn't find good name, so i used this. :( – Anoop Vaidya Mar 05 '13 at 09:27
  • Try my answer here - http://stackoverflow.com/questions/4163579/how-to-detect-the-end-of-loading-of-uitableview/40278527#40278527 – Suhas Aithal Oct 27 '16 at 07:46

3 Answers3

5

You can add a method/category on UITableView or even subclass UITableView:

-(void)reloadDataAndWait:(void(^)(void))waitBlock {
    [self reloadData];//if subclassed then super. else use [self.tableView
    if(waitBlock){
        waitBlock();
    }
}

And you need to use it as

[self.tableView reloadDataAndWait:^{
    //call the required method here                                            
}];
Anoop Vaidya
  • 46,283
  • 15
  • 111
  • 140
  • Hi Anoop, looks like a very interesting approach but Im not sure how to implement it. Do you have any more direction? – Brandon Mar 05 '13 at 08:25
  • I am getting an error "No visible Interface" at the self reloadData line, and where do I put the self.tableview reloadDataAndWait? do I put that in viewdidappear? – Brandon Mar 05 '13 at 08:28
  • use self.tableView reloadData – Anoop Vaidya Mar 05 '13 at 08:30
  • OK, and where do I put the [self.tableView reloadDataAndWait:^{ part? – Brandon Mar 05 '13 at 08:35
  • in your methodA instead of [... reloadData] use this – Anoop Vaidya Mar 05 '13 at 08:37
  • Hi Anoop, still working it - I can see that your answer is correct, I am just trying to implement it properly – Brandon Mar 05 '13 at 09:00
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/25585/discussion-between-brandon-and-anoop-vaidya) – Brandon Mar 05 '13 at 09:00
  • 4
    I am sorry, but I do not see how this is useful. Calling `[self.tableView reloadDataAndWait:^{ [self methodB] }];` is the same as calling `[self.tableView reloadData]; [self methodB];` sequentially. - There would be a difference if you call `reloadData` on a background thread, but that is not allowed. – Martin R Mar 05 '13 at 09:02
  • hi @MartinR - do you have another recommendation on how to go about this? all I really want to do is have an alert displayed if the tableview has no results... it sounds simple, but I can't place the alert in viewdidappear or in various other methods because the query takes a few moments to load... – Brandon Mar 05 '13 at 09:04
  • @Brandon: 1) See my comment to your question. - 2) You have accepted this answer, so it must have solved your problem. – Martin R Mar 05 '13 at 09:07
  • @MartinR: it waits till the method doesn't get completed. and i have used this in my osx application where at a time thousands of rows each having 10 columns, needed to fill. – Anoop Vaidya Mar 05 '13 at 09:08
  • 5
    @AnoopVaidya: There is ***no difference*** between `[self.tableView reloadData]; [self methodB];` and `[self.tableView reloadDataAndWait:^{ [self methodB] }];`. - `reloadData` always returns quickly, the actual updates of the visible cells are done asynchronously. - It is OK if your answer helped Brandon, but I really don't see how. – Martin R Mar 05 '13 at 09:15
  • @Brandon That question is totally different from what you asked so should be a separate question most likely. But it sounds like all is resolved now? – Carl Veazey Mar 05 '13 at 09:21
  • @MartinR the advantage here would be you can pass a block to it instead of hard coding the call to `methodB`, but `reloadAndWait:` is a terribly misleading method name. – Carl Veazey Mar 05 '13 at 09:22
  • Hi all, still a bit shaky on this - I can clarify my question – Brandon Mar 05 '13 at 09:28
  • 1
    @Brandon: I assume that the *real problem* is that you call `reloadData` immediately after starting the URL request. That does not make sense because the request has not been completed at that point. - The correct way would be to call `reloadData` and `methodB` in `connectionDidFinishLoading`, after you have updated your data source with the response from the URL request. – Martin R Mar 05 '13 at 09:33
  • 1
    @MartinR - YOU NAILED IT MARTIN - I have revised the question here. This question was previously closed but has been reorganized. Please feel free to reopen and provide your answer and I will mark correct. You saved me tons of time!! http://stackoverflow.com/questions/15217522/display-alert-if-tableview-has-no-results – Brandon Mar 05 '13 at 09:51
2

The problem is that you call reloadData immediately after starting the URL request. That does not make sense because the request has not been completed at that point.

The correct way would be to call reloadData and methodB in connectionDidFinishLoading, after you have updated your data source with the response from the URL request. At that point you know if the number of rows is zero or not, and there is no need to wait for the table view update to complete.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
2

Once I get updated data from server for my table.

I use following code snip to Hide progress bar when table reload gets complete.

[UIView animateWithDuration:0 animations:^{
            [your_table_view reloadData];
        } completion:^(BOOL finished)
        {
            //Table reload completed TODO here
            //Hide progress bar etc.
        }];
swiftBoy
  • 35,607
  • 26
  • 136
  • 135