TableViewController's Table View not displaying until the data is loaded
I'm facing a strange issue. I have a method which populates an array with some data (fetchData) (quite a lot actually and it's a bit slow). I'm using the array to build the rows of the table.
I've tried calling fetchData in a number of places in my code, at various times in the construction of the view and I always seem to get the following: a black screen which is shown until the data from the array is loaded. I've called fetchData from the following:
- (void)viewDidLoad;
- (void)viewWillAppear:(BOOL)animated;
- (void)viewDidAppear:(BOOL)animated;
Since I'm using a navigation view controller, having the app appear to hang is pretty bad looking since it gets stuck on a black screen. What I was hoping my code would achieve was displaying an empty table, with a progress indicator until the data is loaded 开发者_运维技巧- then refresh. Unfortunately I'm not getting this far since the view isn't being loaded no matter where I call fetchData.
Help appreciated!
P.S. To get around this problem I even tried using a TTTableViewController, but the Loading view is never displayed. Typical. sigh
Your load method must be blocking the UI. You should move it to another thread and let the data load there. You can instantiate the thread in viewDidLoad
.
This is a skeleton code for that you need to (using GCD)
dispatch_queue_t downloadQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(downloadQueue, ^{
... Move all the loading part here.
dispatch_async(dispatch_get_main_queue(),^{
... Do all the UI updates, mostly, [tableView reloadData];
})
})
It possible that you could add a timer to delay the call somewhere in your viewDidAppear
method. For example:
- (void)viewDidAppear:(BOOL)animated {
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(fetchData) userInfo:nil repeats:NO];
}
This will give your app time to load the UI and start your loading screen, then start fetching the data later. You can also try fetching the data in a background thread if you would prefer to go that route
I was having the same issue with a table view not loading initially, but it worked n another .m file I had. Here is the one that worked:
add this to your viewDidLoad:
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
and this to the implementation block:
#pragma mark -
#pragma mark Fetched results controller
- (NSFetchedResultsController *)fetchedResultsController {
if (fetchedResultsController == nil) {
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"OMFrackinG" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
// grouping and sorting optional
//NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"country" ascending:YES];
NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"state" ascending:YES];// was name
NSSortDescriptor *sortDescriptor2 = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1,sortDescriptor2, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
propriate.
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:@"state" cacheName:nil];//@"state"
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
[aFetchedResultsController release];
[fetchRequest release];
[sortDescriptor1 release];
[sortDescriptor2 release];
[sortDescriptors release];
}
return fetchedResultsController;
}
精彩评论