简体   繁体   中英

Content of cell doesn't show immediately after I update the data

I'm now working on an email app. I use a UITableView to show an email list. The list is dynamic. eg user may pull to refresh the list, may also load more mails.

I want to store the mails, so I use CoreData and FetchedResultsController . I've implemented the NSFetchedResultsControllerDelegate .

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
    [self.tableView beginUpdates];
}

- (void)controller:(NSFetchedResultsController *)controller
  didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
           atIndex:(NSUInteger)sectionIndex
     forChangeType:(NSFetchedResultsChangeType)type
{
    switch(type) {
        case NSFetchedResultsChangeInsert:
           [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]     withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}

- (void)controller:(NSFetchedResultsController *)controller
   didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath
     forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath
{
    UITableView *tableView = self.tableView;

    switch(type) {
        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeUpdate:
            [self configureCell:(EmailsTableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade];
        break;
    }
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    [self.tableView endUpdates];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return [[self.fetchedResultsController sections] count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:   (NSInteger)sectionIndex
{
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:sectionIndex];
    return [sectionInfo numberOfObjects];
}

Now the problem is after I download the mails from the server and store them with CoreData object. The tableview show new blank cells first, followed by the real content ( about 3~5 seconds delay ). How can I update the tableview immediately after the model be changed and let the cell content show without delay?

Update

I was updating managed context in background thread which may cause such problem. You should invoke FRC delegate methods in main thread .

Have you tried:

[myTableView reloadData];

After you downloaded all your emails instead of updating sections and rows in sections?

I assume your

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(int)section;

returns the number of elements in your fetched array.

eg

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(int)section
{
    return myArrayOfEmails.count;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM