views:

102

answers:

2

Normally to use UITableView, the number of sections and rows per section are known. But what if they aren't? I want to implement a lazy search, so that I actually search for the next match when new data needs to be displayed. Something on the lines of: db.prepareSearch(query) and then call something like db.nextSearchResult() when it is time to display a new cell. The search result determines if a new section is required or not (search results are inherently sorted).

Not sure why it wasn't done this way to begin with, so that it asks for a section until no more are available or needed, and for cells in the section until no more are available or needed, instead of having to specify the totals, which implies having to finish the whole search before starting to display the first few results.

+2  A: 

To get the number of sections and rows, it's easy -- ask your data source. If your data source has no way of telling you this, make a way.

For instance, if you have to query a table and ask how many rows there are for your sections, do that. Then, for each section, ask how many rows there are which match that section.

What it also sounds like is you want to paginate your data. Meaning when you get to a certain point, have a "load more data" cell or some-such. This is fine too, just add a sentinel node to your data source, and whenever that particular item comes up, display your alternate cell while you load your data, then remove it after your next data is fetched. I do this in a few of my apps.

jer
When you say 'load more data', I take it you add to the datasource and then [table reloadData] right? Won't it visually glitch when doing this?
apalopohapa
It shouldn't glitch when you're doing that. But yeah, every time you add to the data source, or remove from it, change its items order, etc., you will need to reload your data. A common optimization is to just reload what's visible (cells on screen plus typically 2 cells either side of the top cell and bottom visible cell), since the other cells beyond those bounds will be reloaded when they become visible again.
jer
So let's say you can see 10 cells, and are currently looking at #1 though #10, and you told UITableView that you have 1 section and 12 rows. Then the user scrolls down, so cellForRowAtIndexPath will be called for row 11 and perhaps 12. Then I fetch more data, reloadData, and tell UITableView that I have 14 rows. Would it ask for rows #2 to #12 only and not glitch?
apalopohapa
No, if you reloadData it will ask *EVERYTHING* in your data source to reload, whether or not that data is in a visible cell or not. But you can use methods like `reloadRowsAtIndexPaths:withRowAnimation:` to reload selected cells only. I.e., you can call: `[yourTableView reloadRowsAtIndexPaths:[yourTableView visibleCells] withRowAnimation:UITableViewRowAnimationNone]` which will reload just the visible cells.
jer
Awesome. Thanks a lot!
apalopohapa
A: 

If I'm understanding this correctly, at the point of drawing/populating, you will know how many rows/sections you have.

If your changing the underlying data using db.nextSearchResult() then you must be calling [tableView reloadData] to trigger a UI update, at this point you should know how many sections and rows you have.

I have to admit I'm a little confused to the exact issue here.

Alastair Pitts
@Alastair That is the thing, I don't know how many rows/sections are there in total when I start populating. For example, assume you have an alphabetically sorted list of contacts (thousands of). And you want to display those that have the word 'blvd' in their address. You sectionize by first letter of last name. So you start with the first person (Mr. Asdf) and search. Say it is a match, so you have your first result, and you go on and collect say the 8 matches that fit your screen. You don't know how many more you'll find, but at least you can start showing those!(cont. next comment)
apalopohapa
With the lazy search, you'll search the following contacts until you find a match, whenever the user scrolls down. And you'll start populating more and more the data source with search results as they are needed, instead of going through the thousands of contacts so that you can tell UITableView how many rows/sections there are.
apalopohapa