views:

326

answers:

4

After rendering a UITableView with a given datasource, I want to be able to switch to a different one prior to calling reloadData.

Tried doing it in the method

- (void)viewDidAppear:(BOOL)animated;

but as far as I can see this isn't called when all the visible cells are rendered. By placing a breakpoint it seems as if nothing is actually rendered. So I must have misunderstood its actual purpose.

Is there a API callback for that or do I have to programmatically look for it? e.g. in

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

when indexPath holds the index for the last rendered cell in the tableview.

To put it into perspective (somewhat).

Suppose we have a UITableView which has a "static" datasource. Once all the static data is displayed, you want to switch to a dynamic datasource which fetches the data off the internet and reloads each row as fetched.

So I'm actually looking for the "right hook" in which to make that change from one datasource to the other.

Are there any other issues one should be concerned about?

Further clarification. I have written all the required code (e.g. an UITableViewController with the static data initialized, different datasources, background threads for the dynamic views, a delegate to notify the UITableViewController as new data is coming in) what I haven't figured out (what the question is all about) is when to actually make the switch from one datasource to the next.

A: 

UITableView load the cells lazy, in other means it only loads the cells that are visible to the user. When the user then scrolls down, the table view will load the new cells while the "old" cells will be released. There are ways to load the entire data source, but this is not recommended from Apple - since it will be heavy on the memory load of the iPhone.

viewDidAppear() is probably your best bet.

Björn
+2  A: 

When you call reloadData it forces your UITableView to re-query your data source regardless of the amount of data that is already loaded. Also, the cells that are not visible are not being loaded, so practically the last cell is only filled with data if and when you scroll down to it. If you know for sure that all your cells are visible at once, as you might have a small number of them, you might do as you suggested and call your update function when indexPath holds the index for the last cell in the tableview.

Edit:

In the light of your edits, I'm thinking that perhaps the moment you should switch data sources depends on the state of your "live" data - when you've got enough data in it to be able to show enough of it on the screen. That is, let the static data be displayed, and only switch when you've already fetched a number of values in your live data source.
Another idea might be keeping only one mutable data source, with pre-loaded static initial data. As you fetch new "live" values, you start by replacing the ones that you already have, and then continue adding new values if their number exceeds the initial number of static entries.

luvieere
I'm sorry I didn't get the whole picture, but now that you've added the details it seems clearer. I'm editing my answer to reflect the situation as you've described it.
luvieere
+1  A: 

viewDidAppear is all about the view controller, not the table. The table reloading will never call that method.

What you want to do, is better handled either via a delegate approach or using notifications. Set up the static data set in viewDidLoad, but then right away start the background dynamic data fetch. When that fetch is complete, have the code downloading the new data call you either as a delegate, or issue a notification your the view controller with the table listens to, and reset the table view data - then you can simply call reloadData, and the cellForRow:AtIndexPath: method will be called again for the rows on the screen (reload data will also revert back to the top of the table).

Kendall Helmstetter Gelner
A: 

The viewWillAppear: and viewDidAppear: methods are only called when your UIViewController gets pushed on the screen (e.g. by an UINavigationContoller or UITableViewController).

What I would do in your situation is to call a method on your own view controller when your dynamic data source is ready (or whenever you intend to change the data source). In this method set the data source and then call [[self tableView] reloadData];

What you should look out for is, if you are constructing your dynamic data source in the background (which I suppose you do) then you need to call your method on the main thread using performSelectorOnMainThread:

frenetisch applaudierend