Nick
Nick

Reputation: 19684

iOS 7 UITableView indexpath row property is nil

I have a UITableView and it contains a custom UITableViewCell. To test, I have an array that has three strings in it. The UITableView delegate methods are called as expected, however, the tableView:cellForRowAtIndexPath delegate is always passed an NSIndexPath instance whose row property is always == nil:

tableView:cellForRowAtIndexPath is called 3 times (once for each object in my array). I added the tableView from within the designer (storyboard) and created an outlet for it. The UITableViewCell instances appear to be correctly instantiated which each call to this delegate. I just can't wrap my head around why the [indexPath row] value is always nil.

Interface(s):

In the implmentation file:

@interface FirstViewController ()
@property(nonatomic, strong)AppDelegate *sharedDelegate;
@property(nonatomic, strong)NSArray *userList;
@end

In the header:

@interface FirstViewController : UITableViewController <FacebookDelegate>
@property (strong, nonatomic) IBOutlet UITableView *tableView;
@end

Init the custom cell:

-(void)viewDidLoad
{
    [self.tableView registerClass: [ListCategoryCell class]forCellReuseIdentifier:@"ListCategoryCell"];
    self.userList = @[@"d", @"g", @"f"]; // make some test data
}

And the delegate this is driving me mad:

//NSIndexPath.row is nil ?!
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
    static NSString *MyIdentifier = @"ListCategoryCell";
    ListCategoryCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier forIndexPath:indexPath];
    if (cell == nil) {
        cell = (ListCategoryCell *)[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault  reuseIdentifier:MyIdentifier];
    }
    cell.titleLabel.text = [self.userList objectAtIndex:[indexPath row]];
    cell.detailLabel.text = @"Detail";

    return cell;
}

Am I missing something? Thanks!

Working Now

I left out some context (and I should not have) that I believe was very relevant to my problem. I created a UIViewController originally and then added a UITableView to this as the view. In the UITableView I created a custom prototype cell. I did all the house work:

UIViewController implemented the UITableViewDelegate & UITableViewDatasource. Created and outlet for the UITableView. Hooked up all the outlets

Everything seemed to work except for the fact that indextPath.row property was always nil. Some resources I found suggested that custom cells were not visible before the uitableview delegates were called.

In the end I made my class a subclass of UITableViewController. Things started working. I am still curious why my original attempt was failing.

Thanks for everyone's time. Some great comments helped me investigate some topics that are "good to know".

Upvotes: 3

Views: 5242

Answers (1)

efimovdk
efimovdk

Reputation: 368

You need to provide at least two methods in view controller if you want it to manage your table view. They are:

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

-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

You've already provided the second, so your table view actually can produce cells but it doesn't know how many.The default value the first method returns is nil.That is the reason why you don't even have an index path.

Optionally:

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

The default value is one,so you don't need to override this in case you have only one section

Make sure your view controller also follows delegate and datasource protocols.

Upvotes: 1

Related Questions