Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITableViewController will not call cellForRowAtIndexPath BUT numberOfSectionsInTableView and numberOfRowsInSection are indeed set properly

#import "AssignmentsViewController.h"
#import "Assignment.h"

@interface AssignmentsViewController ()

@property NSMutableArray *assignments;
@property (weak, nonatomic) IBOutlet UITableView *tableView;

@end

@implementation AssignmentsViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    NSLog(@"viewDidLoad");
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.assignments = [[MySingleton sharedMySingleton] assignments];
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
}

- (void)viewWillAppear:(BOOL)animated {
    NSLog(@"viewWillAppear");
    [self.tableView reloadData];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    NSLog(@"numberOfSectionsInTableView");
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSLog(@"numberOfRowsInSection");
    return [self.assignments count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"cellForRowAtIndexPath");
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"AssignmentCell"];
    if(cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"AssignmentCell"];
    }
    cell.textLabel.text = [[self.assignments objectAtIndex:indexPath.row] title];
    return cell;
}

@end

Console output when the AssignmentsViewController is loaded and at least one homework assignment is in the assignments array:

2013-11-06 18:55:09.396 Homework Planner[4756:70b] viewDidLoad
2013-11-06 18:55:09.403 Homework Planner[4756:70b] numberOfSectionsInTableView
2013-11-06 18:55:09.405 Homework Planner[4756:70b] numberOfRowsInSection
2013-11-06 18:55:09.408 Homework Planner[4756:70b] viewWillAppear
2013-11-06 18:55:09.409 Homework Planner[4756:70b] numberOfSectionsInTableView
2013-11-06 18:55:09.409 Homework Planner[4756:70b] numberOfRowsInSection

I am making an application that displays the users homework assignments. For some reason, cellForRowAtIndexPath is never called, even when I am sure the assignments array has a homework assignment object in it. The homework assignments are added to the array by a modal view, and I have verified that they are indeed added by that process and after the user taps "cancel" the view returns to the view defined by this class. When that happens the other two methods related to the UITableView run, but not cellForRowAtIndexPath. Please help me solve this problem I am having.

like image 564
ahyattdev Avatar asked Nov 07 '13 02:11

ahyattdev


3 Answers

Check to see if [self.assignments count] is returning 0 (check if self.assignments is nil.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSLog(@"[self.assignments count] = %d", [self.assignments count]);
}

Otherwise, the only other reason I can think of right now, is when height returned by delegate method is 0 (in case you are implementing it, otherwise default implementation always give non-zero height so no issue in that case.)

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
  CGFloat height = 0;
  // Some calculation to determine height of row/cell.

  return height;
}
like image 26
Ashok Avatar answered Oct 24 '22 11:10

Ashok


If cellForRowAtIndexPath is not call it's because the view is not yet rendered on the screen (not drawed), so the system is not able to know the size of the Cell or the UITableView.

To solve that issue make sure that you add your items AFTER the view if rendered (and dimension are known). It can happen if the UITableView is added in a parent view to build complex screen.

If you don't load the data during the init phase, you can call reloadData after setting the data.

Example:

OfferTableViewController * offerList = [[OfferTableViewController alloc] init];

// add the view in the parent view to make sure that the dimension are calculated
[fullSiteView.offersView addSubview: offerList.view]; 
offerList.delegate = self;
// Set the data
offerList.offers = product.offers;
// Force reload to render
[offerList.tableView reloadData];

In addition, if you overwrite heightForRowAtIndexPath make sure that it's return something > 0

Note that even if numberOfRowsInSection and numberOfSectionsInTableView return the right count of items, if the size of the table is unknown, the system will no call cellForRowAtIndexPath

like image 24
sonique Avatar answered Oct 24 '22 13:10

sonique


Let me contribute one more culprit: "Memory management issue".

If TableView's DataSource object is not kept (retain count is zero) while TableView is pulling data from it, then, suprisingly, tableView:cellForRowAtIndexPath: is not called although numberOfSections and numberOfRows do just get called

like image 50
Bùi Thanh Hải Avatar answered Oct 24 '22 13:10

Bùi Thanh Hải