Reputation: 3715
I am quite puzzled why reloadData does not reload the tableview. It does not call numberOfRowsInSection
...
The fetchedResultsController
does get the new row after having saved the new data into core-data
Before adding new data to the tableview
2011-12-29 19:09:08:213 CaveConditions[56423:71939] FRC 170
After viewWillAppear
and adding data
2011-12-29 19:09:35:908 CaveConditions[56423:71939] FRC NEW 171
The tableView (aTableView) is not nil before calling reloadData
2011-12-29 19:18:27:334 CaveConditions[56525:71939] TableVIew: <UITableView: 0x9c12000; frame = (0 0; 320 367); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x751cbb0>; contentOffset: {0, 0}>
As soon as I restart the app it shows the new content... I am using Storyboard and have done all the connection between the tableview and the delegate / data source and checked it multiple times. The Class is a UIViewController.
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.fetchedResultsController = nil;
NSError *error;
if (![[self fetchedResultsController] performFetch:&error]) {
// Update to handle the error appropriately.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:0];
NSLog(@"FRC NEW %d",[sectionInfo numberOfObjects]);
[self.aTableView reloadData];
}
Not sure what the problem is here... Any ideas?
Edit:
I am lazyloading FRC
- (NSFetchedResultsController *)fetchedResultsController
{
if (!fetchedResultsController)
{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
if (isNormalCell)
{
fetchRequest.entity = [NSEntityDescription entityForName:@"Condition" inManagedObjectContext:self.context];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"diveDate" ascending:NO]];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"cave = %@", cave];
} else
{
fetchRequest.entity = [NSEntityDescription entityForName:@"Condition" inManagedObjectContext:self.context];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"insertDate" ascending:NO]];
fetchRequest.returnsDistinctResults = YES;
}
fetchRequest.fetchBatchSize = 20;
fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:context
sectionNameKeyPath:nil
cacheName:nil];
fetchedResultsController.delegate = self;
}
return fetchedResultsController;
}
Here some code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier;
if (!isNormalCell)
CellIdentifier = @"conditionCellReport";
else
CellIdentifier = @"conditionCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// Set up the cell...
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
Condition *condition = [fetchedResultsController objectAtIndexPath:indexPath];
ConditionCell *conCell = (ConditionCell *)cell;
// Reset cell tag which normally contains the ConditionID
conCell.tag = 0;
conCell.img.image = nil;
conCell.lineLabel.text = [condition.line valueForKey:@"line"];
conCell.flowProgress.progress = [[condition.flow valueForKey:@"flowValue"] floatValue];
conCell.percolationProgress.progress = [[condition.percolation valueForKey:@"percolationValue"] floatValue];
conCell.sedimentProgress.progress = [[condition.sediment valueForKey:@"sedimentValue"] floatValue];
conCell.visProgress.progress = [[condition.visibility valueForKey:@"visValue"] floatValue] / 25;
conCell.tag = [condition.ccId intValue];
...
Found another problem. After saving the data and going back to the tableview when trying to scroll it shows only white cells.. it does not reload the old cells too.
Upvotes: 3
Views: 11725
Reputation: 3715
OK! I found the problem. Instead of reloadData I used beginUpdates and endUpdates. Thanks a lot for all your help! I got the information from the NSFetchedResultsControllerDelegate Reference
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView beginUpdates];
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView endUpdates];
}
Upvotes: 5
Reputation: 128
If the added data displays after the app restarts, I would assume that your code is missing the step to add the new data to the array that is supplied to the following method.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
To clarify, the FRC with 171 objects should pass that information on to the array that will be used to reload the UITableView.
Upvotes: 0
Reputation: 21967
If the table is showing the correct data when you restart the app then your tableView dataSource and delegate methods are correct. You mention that the problem occurs after you add new data (i.e. save the managedObjectContext
). If that's the case, then the issue is in your handling of the NSFetchedResultsController
delegate methods.
Try adding the following:
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self.aTableView reloadData];
}
If that fixes the issue, you can animate the table changes vs reloading the whole table. The NSFetchedResultsController
docs have a clear example of how to do this.
Upvotes: 1
Reputation: 1897
in my opinion you try to perform a fetch when the controller is nil. i would try it this way:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.fetchedResultsController = nil;
id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:0];
NSLog(@"FRC NEW %d",[sectionInfo numberOfObjects]);
NSError *error;
if (![[self fetchedResultsController] performFetch:&error]) {
// Update to handle the error appropriately.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
[self.aTableView reloadData];
Upvotes: 1