22

I have a simple problem but I can't understand what is. I have a UIViewControler (called RootController) that load a UIView (called SecondView) that contain a tableView. The problem is that the UIView call the numberOfSectionsInTableView and the numberOfRowsInSection but don't call cellForRowAtIndexPath and the table view is not displayed. The code of the RootViewController is:

SecondView *secondView = [[seconddView alloc] initWithFrame:CGRectMake(0, 60, self.view.bounds.size.width, self.view.bounds.size.height)];
[self.view addSubview:secondView];

And the code of the SecondView is:

@interface SecondView () <UITableViewDelegate, UITableViewDataSource>
@property (nonatomic,retain) UITableView *table;
@end

@implementation SecondView
@synthesize table;

- (id)initWithFrame:(CGRect)frame {
   self = [super initWithFrame:frame];
   if (self) {
   self.table = [[UITableView alloc] init];
   self.table.delegate = self;
   self.table.dataSource = self;
   [self addSubview:self.table];
   }
 return self;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  static NSString *CellIdentifier = @"Cell";
  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
  if (cell == nil) {
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
     }
  cell.textLabel.text = @"Prova";
  return cell;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
   return 5;
}

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

Can you help me to find the problem? Thank you.

Ajay
  • 1,622
  • 20
  • 36
Anna565
  • 735
  • 2
  • 10
  • 21
  • 2
    What is the table view frame? – Wain Jan 29 '14 at 14:37
  • 1
    The previous answer solves it but the real explanation is here: [http://stackoverflow.com/questions/7712325/cellforrowatindexpath-not-called][1] [1]: http://stackoverflow.com/questions/7712325/cellforrowatindexpath-not-called – GrandSteph Dec 05 '14 at 18:42
  • Right answer is here https://stackoverflow.com/questions/7712325/cellforrowatindexpath-not-called – Ramis Nov 10 '17 at 14:44

9 Answers9

51

You need to set the Frame of UITableView

Hussain Shabbir
  • 14,801
  • 5
  • 40
  • 56
14

My problem was that I had a simple class doing the implementing of my delegate and data source, but the lifetime of the simple class was too short.

I was doing

MyDataSourceClass* myClass = [[MyDataSourceClass alloc] initWithNSArray:someArray];
tableView.dataSource = self.tableViewDataSource;
tableView.delegate = self.tableViewDataSource;
[tableView reloadData];

// end of function, myClass goes out of scope, and apparently tableView has a weak reference to it

Needed to be doing

self.tableDataSource = [[MyDataSourceClass alloc] initWithNSArray:someArray];
tableView.dataSource = self.tableDataSource;
tableView.delegate = self.tableDataSource;
[tableView reloadData];
// now at the end of the function, tableDataSource is still alive, and the tableView will be able to query it.

Note that the code above is pseudocode from memory. Take from it the concept of "make sure your data source/delegate lives long", but don't copy paste it, because there's other stuff you need to do (like set your frame etc etc).

ArtHare
  • 1,798
  • 20
  • 22
  • Thank you for the "lifetime of the simple class was too short", this was my issue – Mostafa ElShazly Jun 27 '20 at 08:59
  • Thank you! This was my problem, just needing to set it as a variable in the viewControllers memory and reference that when setting the datasource did the trick. – Adam Apr 06 '23 at 08:14
11

This could also happen if reloadData is called on a different thread. Make sure it is run on the main thread since all UI stuff has to happen on the main thread.

dispatch_async(dispatch_get_main_queue(),{
            self.myTableView.reloadData()
        });
spfursich
  • 5,045
  • 3
  • 21
  • 24
7

In XCode6 same weird problem was occurring to me when "Add Missing Constraints" is applied on tableView on Storyboard to adjust views.

To resolve this issue on Storyboard first clear constraints:

enter image description here

then apply constraints in following fashion:

enter image description here

Aqib Mumtaz
  • 4,936
  • 1
  • 36
  • 33
1

You can only call the viewcontroller's view AFTER viewDidLoad is called. You can't interact with self.view in your init method

- (void)viewDidLoad {
    [super viewDidLoad];
    self.table = [[UITableView alloc] initWithFrame:self.view.bounds];
    self.table.delegate = self;
    self.table.dataSource = self;
    [self addSubview:self.table];
}

In your case, you need to init your tableview with a frame (like a suggested in the code above). Just make sure you add the code in viewDidLoad in your viewController

SecondView *secondView = [[seconddView alloc] initWithFrame:CGRectMake(0, 60,     self.view.bounds.size.width, self.view.bounds.size.height)];
[self.view addSubview:secondView];
Thomas Keuleers
  • 6,075
  • 2
  • 32
  • 35
1

I have same issue like you:

I have only one method from delegate protocol that called and this is numberOfRowsInSection. Meanwhile I have second method cellForRowAtIndexPath that was not called.

The reason of this behaviour was that my numberOfRowsInSection returned 0 rows and cellForRowAtIndexPath didn't call because it needed to draw 0 cells.

wm.p1us
  • 2,019
  • 2
  • 27
  • 38
0

I would comment on Hussain Shabbir's answer, to clarify it, but as I am not yet able to comment, I will post an answer instead.

I had exactly the same issue. numberOfRowsInSection would fire, but cellForRowAt would not. I tore my code apart looking for the reason, but the reason is not in the code.

The solution (for me) was in the storyboard. I had not set constraints for the Table View. Select the table view, click the "Add New Constraints" icon (looks like a square TIE fighter) and set constraints for top, bottm, leading and trailing. Then cellForRowAt will be called and your table will populate.

I hope this helps someone.

ttt
  • 33
  • 4
0

This solution was specific for my case but maybe helps someone.

I had the same problem. I was using a computed property instead of stored property; so every time I call the tableView, I was getting a new one.

I had this code:

var tableView: UITableView{
    let tableView = UITableView()
    tableView.dataSource = self
    tableView.delegate = self
    tableView.register(SomeCell.self, forCellReuseIdentifier: cellID)
    return tableView
}

And this is the fixed code:

lazy var tableView: UITableView = {
    let tableView = UITableView()
    tableView.dataSource = self
    tableView.delegate = self
    tableView.register(SomeCell.self, forCellReuseIdentifier: cellID)
    return tableView
}()
-3

Delete UITableView and add again in your ViewController

Vishal Chaudhari
  • 403
  • 1
  • 6
  • 13