[tableView numberOfRowsInSection:0 always returns 0 - iphone

The data populates, but [tableView numberOfRowsInSection:0] always returns 0. There is only one section in my table. What types of things can cause this behavior?

If there is only one section always in your table, go with the following coed...
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
Or in case your number of sections are depending on datasource, you can return the count of your datasource.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
Try this. It might help you.

Related

Empty sortDescriptors and table view sections

There is something within table sections and sortDescriptors that is driving me crazy. Any help will be much appreciated ;)
What I'm looking for is just displaying an "add" row at the bottom of each self.fetchedResultsController.fetchedObjects section. I'm using a sectionNameKeyPath to show sections in my table view. Up to here everything works perfectly. I've implemented this technique in other parts of my app and works pretty well.
However, the problem comes up when there is no data returned by the FRC and core data doesn't return any entity. If I try to add my first managed object, then app breaks with the following error:
The number of sections contained in the table view after the update
(1) must be equal to the number of sections contained in the table
view before the update (1), plus or minus the number of sections
inserted or deleted (1 inserted, 0 deleted). with userInfo (null)
This is my code so far:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if ([self.fetchedResultsController.fetchedObjects count] == 0) {
return 1;
}
return [[self.fetchedResultsController sections] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
if ([self.fetchedResultsController.fetchedObjects count] == 0) {
return 1;
}
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects] + 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([self.fetchedResultsController.fetchedObjects count] == 0 ) {
static NSString *identificadorCelda2 = #"CeldaNuevoGasto";
UITableViewCell *celda = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:identificadorCelda2];
if (celda == nil) {
celda = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:identificadorCelda2];
}
return celda;
}
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:indexPath.section];
NSInteger nsection = [sectionInfo numberOfObjects];
if (indexPath.row == nsection) {
static NSString *identificadorCelda2 = #"CeldaNuevoGasto";
UITableViewCell *celda = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:identificadorCelda2];
if (celda == nil) {
celda = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:identificadorCelda2];
}
return celda;
}
static NSString *CellIdentifier = #"CeldaGasto";
CeldaGastos *cell = (CeldaGastos *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = (CeldaGastos *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
} .....
For sure I'm doing something wrong, but I can not figure it iut. Do I need to modify NSFetchedResultsController delegate methods as well to respond to additions? Or is it something easiser. Thanks ;)
Update
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
NSInteger nsection = [self.fetchedResultsController.sections count];
switch(type) {
case NSFetchedResultsChangeInsert:
if (nsection == 1 && [sectionInfo numberOfObjects] == 1) {
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
}
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
if (!nsection)
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
If I understand your situation correctly, then you indeed will have to change the NSFetchedResultsController delegate methods as well.
Are you inserting new sections into table view using the -insertSections:withRowAnimation: method of your table view from some of the NSFetchedResultsController's delegate callbacks?
I do not know exactly what your NSFetchedResultsControllerDelegate's implementation is, but for example consider this situation step by step:
Initially you have no entities fetched, and your -numberOfSectionsInTableView: method returns 1 for your 'add' row.
After you've inserted an entity and the NSFetchedResultsController's delegate receives its -controller:didChangeSection:atIndex:forChangeType: callback, where you insert a new section into table view using -insertSections:withRowAnimation:
The table view asks its dataSource by calling the -numberOfSectionsInTableView: method expecting it to rerurn a value increased by 1 (since you are inserting 1 new section). But the method does still return 1 because the 'add' row is not taken into account anymore.
That will result exactly in the error which you are having.
I guess calling -deleteSections:withRowAnimation: to remove the 'add' row when it is not needed anymore will solve your problem.

UITableView Index without magnifying glass

I am trying to create an Indexed UITableView with out the magnifying glass icon.
I realize the UITableViewIndexSearch is creating the icon in the index but I do not know what to replace it with. Any help or suggestions would be greatly appreciated.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [[self.fetchedResultsController sections] count];}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
return index;}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
// Return the array of section index titles
NSArray *searchArray = [NSArray arrayWithObject:UITableViewIndexSearch];
return [searchArray arrayByAddingObjectsFromArray:self.fetchedResultsController.sectionIndexTitles];}
Simply replace it with nothing. Just leave the UITableViewIndexSearch constant out of your array.
Don't add UITableViewIndexSearch in sectionIndexTitlesForTableView:. Simply return the array from your fetchedResultsController.

NSFetchResultController Delegate Error

I have a couple of UIViewControllers that show a table view of my 'User' objects as the section, and 'Site' objects as rows under each section. The Site to User relationship is one-to-many.
At the moment I am showing this data with the following code:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:0];
return [sectionInfo numberOfObjects];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
User *sectionUser = (User*)[self.fetchedResultsController objectAtIndexPath:[NSIndexPath indexPathForRow:section inSection:0]];
return [[sectionUser.sitesToUser allObjects] count];
}
In my NSFetchResultsController I'm just pulling all User objects, nothing special.
Now my issue - whenever I update the results, by removing a section (ie a User) or adding a User whilst this view is also open, I get an NSFetchedResultsController delegate error:
Serious application error. An exception was caught from the delegate of
NSFetchedResultsController during a call to -controllerDidChangeContent:. Invalid
update: invalid number of sections. The number of sections contained in the table
view after the update (2) must be equal to the number of sections contained in the
table view before the update (1), plus or minus the number of sections inserted or
deleted (0 inserted, 0 deleted). with userInfo (null)
I only get it in the views where I am displaying my data in this way, is User is section, Site/s are rows under each section.
Am I doing something really stupid? I thought it would just remove the section when I delete it etc... Seems to work fine if each User is a ROW in the UITableView - which I believe is the crux of my issue...
I'm using Core Data but my code for numberOfSectionsInTableView: and tableView:numberOfRowsInSection: method is different... I don't know if this can solve your problem but, try to use this code:
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[self.fetchedResultsController sections] count];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger rowsNumber = 0;
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
rowsNumber = [sectionInfo numberOfObjects];
return rowsNumber;
}
For the sections, I've never used it but try to work on the sectionNameKeyPath argument of the initWithFetchRequest:managedObjectContext:sectionNameKeyPath:cacheName: when you initialize your controller.
You haven't shown your fetchedResultsController delegate calls:
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
- (void)controller:didChangeObject:atIndexPath:forChangeType:newIndexPath
- (void)controller:didChangeSection:sectionInfoAtIndex:forChangeType:
These calls are responsible for adding and removing the rows / sections from your table so everything "adds up" as far as the tableview is concerned.
In your case you are kind of "abusing" what a section is so this code could get tricky.
If you are prepared to do without animation you could just implement:
-(void)controllerDidChangeContent:(NSFetchedResultsController*) controller {
[self.tableView reloadData];
}
Daniel.

Number of rows from tableview

I was working with the tableview and I wanted the number of rows (i.e the number of items in tableview). How can I get the number of rows, if available?
Please help me out,
thanks in advance.
take a instance variable in your header file.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
yourHeaderFileVariable = [noOfItemsInArray count];
NSLog(#"total item in table %d",yourHeaderFileVariable);
return [noOfItemsInArray count];
}
or try this
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section {
NSLog(#"total item in table %d",[noOfItemsInArray count]);
return [noOfItemsInArray count];
}
The number of rows in table view for a section is what you are returning from (NSInteger)tableView:numberOfRowsInSection:. So if you return something like [mySource count] from this method then the number of rows is [mySource count].
For example:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [data count];
}
// to get the count
NSInteger rowCount = [data count];
Now replace [data count] with whatever calculation you have in the delegate method.
You need to implement the delegate method :
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [yourArray count];
}
You can then show the result in the table header by using the following delegate method :
- (NSString *)tableView:(UITableView *)resultTableView titleForHeaderInSection:(NSInteger)section
{
NSString *str=[NSString stringWithFormat:#"%i",[yourArray count]];
str=[str stringByAppendingString:#" matches"];
return str;
}
For example, if you have 7 results in the table, the header will display the text "7 matches"
- (NSInteger)tableView:(UITableView *)tablefirst numberOfRowsInSection:(NSInteger)section {
int count;
count=0;
count=[*your array name* count];
NSLog(#"row count=%d",count);
return [*your array name* count];
}
This function returns the number rows(items) in your tableview
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [listOfItems count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return numberOfRows;
}

Delete UITableView row issue

I'm having a problem that I see a lot of people having... however none of the fixes are working for me. But I did notice something odd happening when I put NSLog commands in the code.
I have the standard delete method:
- (void) tableView: (UITableView *) tableView commitEditingStyle: (UITableViewCellEditingStyle) editingStyle forRowAtIndexPath: (NSIndexPath *) indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.recipes removeObjectAtIndex: indexPath.row];
[tableView beginUpdates];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject: indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
}
}
recipes is the array that holds the data source.
Theoretically this should work just fine, but I get the error:
invalid number of rows in section 1. The number of rows contained in an existing section after the update (9) must be equal to the number of rows contained in that section before the update (10), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted).
But I know where this is falling apart, when I add an NSLog into the numberOfRowsInSection, I see that the method is being called twice from the method above.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
NSLog(#"THIS CALLED TWICE %i",[recipes count] );
return [recipes count];
}
Anyone know what else could cause the numberOfRowsInSection method to fire twice?
Thank you for your time.
After writing this, I saw that I had the following:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 2;
}
Apparently, numberOfRowsInSection is called for each section... changing the code to:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
Fixed the issue.