Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

tableView reloadData not working

Tags:

When I call [tableView reloadData] the function - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath is not fired? Why?

Here's my TableView.m

@implementation TableView @synthesize managedObjectContext; @synthesize controller = _controller; @synthesize tableView = _tableView;  - (id)initWithFrame:(CGRect)frame {     self = [super initWithFrame:frame];     if (self) {      }     return self; } -(id)init {     self = [super init];     if (self) {         NSLog(@"%s",__PRETTY_FUNCTION__);         self.del = [[UIApplication sharedApplication] delegate];         self.managedObjectContext = self.del.managedObjectContext;          [self performControllerFetch];     }     return self; }   #pragma mark - Table view data source  - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {     ... }  - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {     ... }  - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {     ... }  - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {      ... }  -(void)reloadTableView {     NSLog(@"%s",__PRETTY_FUNCTION__);      [self.tableView reloadData];  }  - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {      NSLog(@"%s",__PRETTY_FUNCTION__);     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.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]                                   withRowAnimation:UITableViewRowAnimationFade];             break;          case NSFetchedResultsChangeMove:             [tableView deleteRowsAtIndexPaths:[NSArray                                                arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];             [tableView insertRowsAtIndexPaths:[NSArray                                                arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];             break;     } }   - (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id )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)controllerDidChangeContent:(NSFetchedResultsController *)controller {     // The fetch controller has sent all current change notifications, so tell the table view to process all updates.     [self.tableView endUpdates]; }  @end 

TableView.h

@interface TableView : UITableView <UITableViewDataSource, UITableViewDelegate, NSFetchedResultsControllerDelegate>  @property (nonatomic, strong) NSManagedObjectContext *managedObjectContext; @property (nonatomic, strong) AppDelegate *del; @property (nonatomic, strong) NSFetchedResultsController *controller; @property (weak, nonatomic) IBOutlet TableView *tableView;  -(void)reloadTableView; -(void)performControllerFetch; @end 
like image 933
iCode Avatar asked Oct 10 '13 17:10

iCode


2 Answers

It looks like you are never setting the delegate and datasource properties on your tableview, no? You're implementing the methods in those protocols inside tableview.m but not setting the two properties to self hence calling reloadData having no effect.

Does this help?

Edit:

Looks like you have a tableView property set on a subclass of UITableView and hooked up to an interface builder file. This is an odd setup (a tableview within a tableview). Usually you would have something like a UIViewController subclass hooked up to an XIB and set an

@property (nonatomic, strong) IBOutlet UITableView * tableView

in that subclass, or something similar. And then handle the data fetching and tableview delegate/datasource inside that viewcontroller subclass.

But here, because of the nested UITableViews it's not as straightforward. Is there a reason for this design? I recommend moving to something like I describe above to help bring clarity to the setup.

Also, try adding some NSLog statements into your init method to see if the tableview != nil and the delegate and datasource properties have been set. My suspicion is that the connection is not being made.

Also, unrelated to the problem at hand, you no longer have to manually @synthesize ivar = _ivar, it will be done for you automatically using the underscore convention.

like image 96
Alfie Hanssen Avatar answered Oct 22 '22 19:10

Alfie Hanssen


I was having the same issue, that the reload was not working. I believe the delegate method I was calling it from was in a background thread which was causing the problem. My solution was to create a new method (below) and call the reload from there instead, while also ensuring to call it from the main thread:

- (void) tocLoad {     dispatch_async(dispatch_get_main_queue(), ^{     [self.tableView reloadData];     }); } 
like image 38
user3730468 Avatar answered Oct 22 '22 19:10

user3730468