views:

65

answers:

1

I am using a standard navigator interface on the iPhone. When I move from the highest level tableview to the next level, I have to load about 2000 records from core data, which can take 5-10 seconds, so I want to use an activity indicator.

I have done the following code which works if I remove the code in the DidSelect method, but otherwise the indicator never appears, even though the view still waits there while the other view loads. Here are the methods:

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath;
{   
[tableView deselectRowAtIndexPath:indexPath animated:YES];

//-- start activity indicator (will be stopped when view disappears)
UITableViewCell * cell = [tableView cellForRowAtIndexPath:indexPath];
[cell.contentView addSubview:m_activityIndicator];
[m_activityIndicator startAnimating];


return indexPath;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {



//--show the listViewController
CardListViewController *listViewController = [[CardListViewController alloc] initWithNibName:@"CardListViewController" bundle:nil];
NSString* selectedCardTypeName = [rootSelectionList objectAtIndex:indexPath.row];
enum CardTypes selectedCardType = cardTypeIDFromCardTypeName(selectedCardTypeName);
listViewController.selectedCardType =selectedCardType;
[self.navigationController pushViewController:listViewController animated:YES];
[listViewController release];


}

How can I force the activity indicator to show up before it starts processing the the next listviewcontroller?

+3  A: 

First of all, why do you need to load the 2k rows at the same time? Why don't you do it lazily?

First, when loading the table view, you would use your datasource to only count the number of rows that you would display, querying the core data to get only the number, and so your table view would be ready to show all the necessary cells.

Second, load from core data only the content that you would need, it means, only the content on screen. Imagine if the user drag and scroll the table view very fast, many cell would be loaded without the need for it. The right thing to do is loading only the visible cells and it means the ones that would be visible when the scrolling process stops.

Have a look at this example from Apple on how to load resources for table view lazily: http://developer.apple.com/iphone/library/samplecode/LazyTableImages/Listings/Classes_RootViewController_m.html#//apple_ref/doc/uid/DTS40009394-Classes_RootViewController_m-DontLinkElementID_12

It's for images, but you can do the same idea for the fetching of objects.

Doing this lazily you wouldn't need the activity indicator.

BTW, going back to the issue with the activity indicator, you may need to ask you cell to update:

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath;
{   
    [tableView deselectRowAtIndexPath:indexPath animated:YES];

    //-- start activity indicator (will be stopped when view disappears)
    UITableViewCell * cell = [tableView cellForRowAtIndexPath:indexPath];
    [cell.contentView addSubview:m_activityIndicator];
    [m_activityIndicator startAnimating];
    [cell setNeedsDisplay];

    return indexPath;
}

Cheers

vfn
Unfortunately setNeedsDisplay didn't work, but I am very interested in your advice regarding the lazy loading of the table. Before i read the example, is it very complicated if it is an indexed table with a search facility?
WaterBoy
you don't need to pay attention on the indexation or search. for your case, you can consider that you would have only one section and forget about the search. What you should really understand is why and where to call [self loadImagesForOnscreenRows]; that is where the lazy loading is done.
vfn
I had a look, but I don't think it will benefit me as I have to get all the records for the 'name' which is used to populate my indexed tableview list. If I am getting the name, I may as well get the complete record.
WaterBoy
Hey WaterBoy, CoreData has some interesting features that helps us to save memory. You can ask core data to load only part of the object that you need, and so, if you need only to display the name, you can set your fetch request to fetch only name, or maybe other properties that you would need to put on the table. Try to use a NSFetchedResultsController to help you with the fetching. It can cache some request to improve the performance on recurrent fetches.
vfn