Chris
Chris

Reputation: 3715

UITableView reloadData does not reload

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.

enter image description here

Upvotes: 3

Views: 11725

Answers (4)

Chris
Chris

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

Jin
Jin

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

XJones
XJones

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

pmk
pmk

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

Related Questions