简体   繁体   中英

iOS - cellForRowAtIndexPath not called on reloadData

I know that this question have been asked so many times but unfortunately non of the solutions in those questions worked for me.

Here are some of the things I tried:

  1. making sure that numberOfSectionsInTableView is not returning 0
  2. making sure that numberOfRowsInSection is not returning 0.
  3. insuring that reloadData is being called on the main thread by using performSelectorOnMainThread as shown below:

    [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO]

  4. setting the delegate in viewDidLoad, as shown below:

    • (void)viewDidLoad { [super viewDidLoad]; // ..... self.tableView.dataSource = self; self.tableView.delegate = self; }

I'm creating an iOS app that keeps track of events. The app's main view is a UITableViewController (Calling it main list) that is embedded into a UINavigationController which is embedded into a UITabViewController . The user can create two objects a list or an event. When a new list is created and selected from the current UITableViewController , a new UITableViewController is pushed into the same UINavigationController .

Each list ( UITableViewController ) has an edit button that allows the user to delete the list.

Assuming that the user chooses to delete "list 3" that belongs to the main list, that is there are 3 view controllers pushed to the UINavigationController:

  1. UITableViewController for the main list
  2. UITableViewController for the selected list "list 3"
  3. UITableViewController for the edit list view

when the delete button is tapped on, an alert is shown. If the user chooses to proceed the following code gets executed:

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    // .....
        //here I'm calling unwind which is going to pop the UITableViewController
        //for the edit table view
        [self performSegueWithIdentifier:@"unwindFromDelete" sender:nil];
        //here I'm calling a method i wrote to pop the UITableViewController
        //of the deleted list (in this example "list 3")
        [self setNavigationControllerViewControllers];
    // .....
}

- (IBAction)unwindFromEditListToList:(UIStoryboardSegue *)segue {
    .....
}

- (void)setNavigationControllerViewControllers {
    NSMutableArray *viewControllers = [[self.navigationController viewControllers] mutableCopy];
    [viewControllers removeLastObject];
    [self.navigationController setViewControllers:viewControllers];
}

After that code is executed, viewWillAppear for the main list UITableViewController is executed as shown below:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    // ..... update the data
    [self.tableView reloadData];
}

[self.tableView reloadData] is going to cause the following code to be executed:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // .....
    return someValue; // Something greater than zero
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    // .....
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // .....
    return someValue; //Something greater than zero
}

#pragma warning "Not getting called"
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // .....
}

All the methods are executed but cellForRowAtIndexPath is not. The problem is gone if setNavigationControllerViewControllers mentioned above is not called. Not calling setNavigationControllerViewControllers will result in UITableViewController for "list 3" to show which is bad since "list 3" is no longer stored in the core data I'm using to store the data.

If you have any idea what to do, please let me know.

Thanks

numberOfSectionsInTableView must return at least 1. See this link below.

You don't even need to override it if you're not using multiple sections.

If the height of table is dynamic. Make sure the table is in a view, visible and height is atleast 1px when reload is called.

I put an answer on this because I've been browsing for a solution for sometime and this question is the closest to the one I was asking myself...

It turns out that I was using auto-layout with visual format. Seems that UITableView and NSLayoutContraint don't play well together. As soon as I commented the method which apply constraints, the cellForRowAtIndexPath was called and the tableview displayed...

Please put debug point on this,

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

method and log someValue value may it return 0 that's why cellForRowAtIndexPath method not called.

Thanks.

Don't know who down voted Avalerion answer, but his statement is important too.

I had same problem, delegate method cellForRowAtIndexPath was not called though the following conditions were matched:

  • Delegate and Datasource was set
  • numberOfSectionsInTableView method was returning 1
  • numberOfRowsInSection returned correct number and data was available.

Reason:

  • I didn't set height constraint for the table, so it had no height, thus app didn't call cellForRowAtIndexPath even though it called eg numberOfRowsInSection.

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