Reputation: 8138
I have splitViewController which has as MasterViewController some viewController and as DetailViewController some tableViewController. When I push a button on masterViewController I want to show new tableViewController in detailViewController instead of existing one.
So I did like this:
SearchDetailViewController *searchDetailViewController = [[SearchDetailViewController alloc] initWithStyle:UITableViewStylePlain];
UINavigationController *searchDetailNavigationController = [[UINavigationController alloc] initWithRootViewController:searchDetailViewController];
After that I'm passing data to show in new tableController:
[searchDetailViewController passInSearchResults:listOfItems];
After that I "push" new controllers to splitViewController:
[searchSplitViewController setViewControllers:[NSArray arrayWithObjects:self.navigationController, searchDetailNavigationController, nil]];
In the target tableViewController method "passInSearchResults" data is passed and I also call reloadData. Method looks like that:
- (void)passInSearchResults:(NSMutableDictionary *)searchResults {
self.searchResultList = searchResults;
NSLog(@"Data is passed in: %@",self.searchResultList);
[self.tableView reloadData];
//[self.tableView setNeedsDisplay];
}
Console: Data is passed in: [here I get the exact data I want and it seems just right].
After this I see that method "numberOfRowsInSection" is fired:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(@"Setting table length: %i",[self.searchResultList count]);
return [self.searchResultList count];
}
Console: Setting table length: [here I get proper length]
The problem is that the table is not filled with passed data and method "cellForRowAtIndexPath" is not called.
How can it be that on reloadData method "numberOfRowsInSection" is fired but not method "cellForRowAtIndexPath"... ???
Thanks
Upvotes: 9
Views: 10330
Reputation: 572
Check if you are in main thread when calling [self.tableView reloadData];
- (void)passInSearchResults:(NSMutableDictionary *)searchResults {
if ([NSThread isMainThread]) {
self.searchResultList = searchResults;
NSLog(@"Data is passed in: %@",self.searchResultList);
[self.tableView reloadData];
}
else {
[self performSelectorOnMainThread:@selector(passInSearchResults:) searchResults waitUntilDone:NO];
}
}
Upvotes: 10
Reputation: 618
In my case the problem was that the reloadData() function was not called from the main thread.
I have changed this by placing it in a dispatch_async() function, which solved the problem:
dispatch_async(dispatch_get_main_queue(), {
self.tableView.reloadData()
})
Hope this helps others.
Upvotes: 3
Reputation: 871
My "AutoLayouted" UITableView did not call cellForRowAtIndexPath on reloadData, because I set the frame by mistake.
_tableView = [[UITableView alloc] initWithFrame:self.view.frame];
_tableView.translatesAutoresizingMaskIntoConstraints = NO;
By changing it to CGRectZero, it worked..
_tableView = [[UITableView alloc] initWithFrame:CGRectZero];
_tableView.translatesAutoresizingMaskIntoConstraints = NO;
Upvotes: 0
Reputation: 1155
Also you can be allocating table in init[With...] method of viewController and also wired up same property in IB. This way it's possible that numberOf... delegate methods are called and cellForRow... does not.
Upvotes: 0
Reputation: 1435
I had the same problem, but decision was very simple. First of all, could you try to scroll table down? tableView:cellForRow... should be called. Check for headers' heights and contentOffset for tableView.
Upvotes: 1
Reputation: 1691
How can it be that on reloadData method "numberOfRowsInSection" is fired but not method "cellForRowAtIndexPath"... ???
After spending a day with the same(ish) issue, I think we found a bug here. I did find a hack/workaround though.
If I alter the array (adding/removing values or completely building it again) that is used in my cellForRowAtIndexPath method, it seems to correctly call cellForRowAtIndexPath again when you reloadData.
For example, in my cellForRowAtIndexPath I have something like:
cell.textLabel.text = [[[self.searchResultsArrayWithSections objectAtIndex:indexPath.section] objectForKey:@"rowValues"] objectAtIndex:indexPath.row];
return cell;
I also have a method to build this array that gets called on viewDidLoad:
- (NSMutableArray *)splitIntoSectionsWithAlphabet:(NSMutableArray *)myArray
{
NSString *letters = @"abcdefghijklmnopqrstuvwxyz";
NSMutableArray *content = [NSMutableArray new];
//code to build array here, nothing special really
return content;
}
So I noticed that if I specifically call this method again on my searchResultsArrayWithSections array before calling reloadData, it actually calls all of the UITableViewDelegate methods correctly! (like I said, hack but it works!)
//dirty hack, bug with cancel button and not realoding data, seems we have to modify this array before it will work correctly
self.customerListArrayWithSections = [self splitIntoSectionsWithAlphabet:self.customerListArray];
[self.customerListTv reloadData];
Upvotes: 4