Hiding a specific row of UITableViewCell - iphone

I am working on a todo list application with CoreData + UITableView, I would like to hide the row that the user mark as done.
My current solution is invoke deleteRowsAtIndexPaths when user mark the task done and deduct the deleted row from the function of numberOfRowsInSection.
-(void)markDone:(NSIndexPath *) _indexPath{
[self.tableView beginUpdates];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:_indexPath] withRowAnimation:UITableViewRowAnimationFade];
deletedCount = deletedCount + 1;
[self.tableView endUpdates];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
if (deletedCount>0) {
return [sectionInfo numberOfObjects]-deletedCount;
}
return [sectionInfo numberOfObjects];
}
Although this method does work, but I do need some code hacking here and there. Is there a way to invoke NSFetchedResultsController didChangeObject for changing of status of particular field?
Thanks

I think there are many ways to solve this. I'd just add a field in your managed object which states if a row is hidden or not"
Deleting will set this field accordingly.
What you need now is an NSFetchRequest with the corresponding predicate to filter hidden rows.
I just created a simple template app with core data support, and I think it is very easy to achieve:
I added a hidden BOOL property to the one entitiy given, with default NO.
Then I added this code to didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSManagedObject *selectedObject = [[self fetchedResultsController] objectAtIndexPath:indexPath];
[selectedObject setValue:[NSNumber numberWithBool:YES] forKey:#"hidden"];
}
In - (NSFetchedResultsController *)fetchedResultsController {... I added
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"hidden == NO"];
[fetchRequest setPredicate:predicate];
after
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
This was it to hide cells by clicking(just for this example) on them.

Related

uiTableView crashes the second time in deleting a cell

I'n new in iPhone, I'm trying to delete a cell from my UITableView, the first time it deletes well, but the second time it gives me the following error:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: 'Invalid update: invalid number of rows in section 0. The number of rows
contained in an existing section after the update (3) must be equal to the number
of rows contained in that section before the update (3), plus or minus the number
of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or
minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
here is my code of table:
- (void)tableView:(UITableView *)tableView commitEditingStyle: (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
Book_own *temp= (Book_own *)[self.books objectAtIndex:indexPath.row];
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[books removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
isDeleted = #"true";
deletedBook_id = temp.bo_id;
[self viewDidLoad];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
NSDictionary *dictionary = [listOfItems objectAtIndex:section];
NSArray *array = [dictionary objectForKey:#"myBooks"];
return [array count];
}
in ViewDidLoad I wrote the following code:
NSDictionary *mbooks = [NSDictionary dictionaryWithObject:books forKey:#"myBooks"];
NSDictionary *mgroups = [NSDictionary dictionaryWithObject:filteredParts forKey:#"myBooks"];
listOfItems = [[NSMutableArray alloc] init];
[listOfItems addObject:mbooks];
[listOfItems addObject:mgroups];
Can anyone tell me how to solve this issue??
Thanks in advance.
What is happening is that you are either not deleting the item or you are deleting only one item when you allow multible deleting. You can adjust by checking if it is really deleted as below or reload data if not:
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
BOOL success = [self removeFile:indexPath];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
if (!success) [tableView reloadData];
}
}
This method then removes the datasource item (it is from my own project so the names should be adjusted:
-(BOOL) removeFile:(NSIndexPath *)indexPath{
// Removes from the datasource and the filesystem
NSURL *fileURL = [self.dataSource objectAtIndex:indexPath.row];
NSError *error;
BOOL success = [[NSFileManager defaultManager] removeItemAtURL:fileURL error:&error];
if (success) {
[self.dataSource removeObjectAtIndex:indexPath.row];
} else {
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Error" message:[error localizedDescription] delegate:self cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[alert show];
[alert release];
[self.dataSource removeObjectAtIndex:indexPath.row];
}
return success;
}
If I'm reading your code correctly your data source is listOfItems. You should remove the row from your tables data source. A general rule is that when you remove or add items to a UITableView you must update the databsource.
[listOfItemsremoveObjectAtIndex:indexPath.row];
First, do not call [self viewDidLoad]; This method should not be called manually.
I think you are not calling the update method to your table view. This might fix your problems:
[tableView beginUpdates];
[books removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
edit: you also need to look at your code more closely. You are deleting a record from your datasource array directly from the row of the indexPath, which could be problematic considering the fact that your tableView has two sections.
The error says that there should be 1 fewer row after the deletion. It fails because the datasource code is not consistent in how it reports about the model.
Look at how you answer numberOfRowsInSection. Correctly, I think, first picking out the array that the section index represents, then answering that array's count.
The same logic must apply on the delete. The array you delete from needs to be the array indicated by the indexPath.section. Consider this:
- (void)tableView:(UITableView *)tableView commitEditingStyle: (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
// the array you manipulate here must be the same array you use to count
// number of rows, and the same you use to render rowAtIndexPath
NSDictionary *dictionary = [listOfItems objectAtIndex:indexPath.section];
NSArray *array = [dictionary objectForKey:#"myBooks"];
// in order to be edited, it must be mutable
// you can do that on the fly here, or set it up as mutable
// let's make it temporarily mutable here:
NSMutableArray *mutableCopy = [array mutableCopy];
if (editingStyle == UITableViewCellEditingStyleDelete) {
[mutableCopy removeObjectAtIndex:indexPath.row];
// if it's setup mutable, you won't need to replace the immutable copy in the dictionary.
// but we just made a copy, so we have to replace the original
[listOfItems replaceObjectAtIndex:indexPath.section withObject:[NSArray arrayWithArray:mutableCopy]];
// and so on

How to delete the NSManagedObject instance from Data Source?

I am trying to override tableView:commitEditingStyle:editingStyleforRowAtIndexPath: and having trouble implementing the deletion of the actual instance of a NSManagedObject that is represented in that row.
Apple says it should be done with the following code(Shown Here):
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the managed object at the given index path.
NSManagedObject *eventToDelete = [eventsArray objectAtIndex:indexPath.row];
[managedObjectContext deleteObject:eventToDelete];
// Update the array and table view.
[eventsArray removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
// Commit the change.
NSError *error = nil;
if (![managedObjectContext save:&error]) {
// Handle the error.
}
}
}
When I mimick this sample code in my app, every line works except for one line. The one line is: [bowlerArray removeObjectAtIndex:indexPath.row];. I get the error "Receiver type 'NSArray' for instance message does not declare a method with selector 'removeObjectAtIndex'".
What should that one line of code be?
Note: My line NSManagedObject *eventToDelete = [bowlerArray objectAtIndex:indexPath.row]; works just fine.
Update: Posting my actual code:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *moc = [appDelegate managedObjectContext];
NSManagedObject *objectToDelete = [bowlerArray objectAtIndex:indexPath.row];
[moc deleteObject:objectToDelete];
[bowlerArray removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
NSArray is immutable, so you can't modify it.
removeObjectAtIndex is not part of the NSArray API, because it would modify it.
You need an NSMutableArray to be able to do that.
If I do this :
NSMutableArray *arMu = [NSMutableArray arrayWithObjects:#"0", #"1", #"2", #"3", #"4", nil];
[arMu removeObjectAtIndex:0];
self.bigLabel.text = [arMu objectAtIndex:0];
the bigLabel is showing 1 for the index 0.
You error message is suggesting that you still have a NSArray instead of an NSMutableArray for the variable eventsArray
You can make a NSMutableArray from a NSArray like this :
NSMutableArray *arMu = [[NSMutableArray alloc] initWithArray:someNSArray];

Traverse the values of many-to-many relationships?

I am a noob when it comes to traversing Core Data many-to-many relationships (I have read numerous threads and documentation on this so unless it's and end all, please no links to documentation or threads).
I am making an inventory application and currently have a Core Data model that includes an "Thing", "Category", "Location", and "ThingLocation" (ThingLocation is an entity that holds both a Thing and Location reference but includes the amount of Things on that particular Location. Also a many-to-many relationship) Entities that I would like to populate my UI with. I am proficient in GUI so this is not a question of User Interface but rather how I would gather the information using (probably) NSPredicates.
Ex: If I show a TableView consisting of a Category entity's details then how would I populate it with the Things in that Category Entity.
Ex: If I wanted to display a UILabel showing the total amount of Thing's there were in it. (i.e. add up all of the amounts on each Location).
EDIT: I want to be able to use an NSFetchedResultsController!
I am not exactly sure what your question is asking. So for example you want to iterate over all the categories and all the things in that category you would first do a request for the entities of category without a predicate (this will return all category objects) and iterate over all those with fast enumeration:
//iOS 5 way of doing it
NSFetchRequest* request = [NSFetchRequest fetchRequestWithEntity:#"Category"];
NSArray* arrayOfObjects = [context executeFetchRequest: request withError: nil];
for (Category* cat in arrayOfObjects)
{
//iterate over all the things in that category
for (Thing* thing in cat.things){
{
//do something?
}
}
For your first example of populating a tableview with things in a category,
If you have the category you would get the Things very easily like this:
NSSet* things= category.things;
//you can get it into an array by sorting it somehow or just get it like that.
NSMutableArray* things = [[category.things allObjects] mutableCopy];
You can iterate over this in a very normal fashion or use them as your datasource for your tableview. If you don't have the category you need something to distinguish it in which case you would set up the predicate like this:
NSFetchRequest* request = [NSFetchRequest fetchRequestWithEntity:#"Thing"];
NSPredicate* pred = [NSPredicate predicateWithFormat:#"(relationToCat.DestAtt = %#)",howToDestinguish];
This will return all the Things that are connected to a category that has that attribute.
For your second example, You would set the NSPredicate up to get all the ThingLocations for that specific Thing. Then iterate over them and add up the values at the locations. If you wanted to do this for every category over everything it would just require you to nest some for loop starting with the categories. then for each thing get all the ThingLocations and for each of those add up the values.
I hope that answers your questions. To-Many relations are just sets and can be treated as such. I find that thinking from the bottom up helps me form the predicates. thinking I need all the things in this category so I would set up with the entity of Things and connecting it back to the category in the predicate.
Edit: NSFetchedResultsController example
In your .h file after declaring your super class add NSFetchedResultsControllerDelegate to the delegates implemented.
Create an ivar:
#property (nonatomic, retain) NSFetchedResultsController* fetchedResultsController;
On the implementation side I've seen two different approaches, the first is writing a custom accessor for the property that initializes it there, the other is just to do it in the viewDidLoad in either case the setup is as follows:
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Thing" inManagedObjectContext:context];
NSPredicate* pred=[NSPredicate predicateWithFormat:#"(relToCat.something=%#)",something];
[fetchRequest setPredicate:pred];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:20]; //tells it how many objects you want returned at a time.
//this is for displaying the things in some sort of order. If you have a name attribute you'd do something like this
NSSortDescriptor *descriptor = [[[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES] autorelease];
NSArray *sortDescriptors = [[[NSArray alloc] initWithObjects: descriptor, nil] autorelease];
[fetchRequest setSortDescriptors:sortDescriptors];
//this is the set up. If you put a sectionNameKeyPath it will split the results into sections with distinct values for that attribute
NSFetchedResultsController *frc = nil;
frc = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context] sectionNameKeyPath:#"attribute that splits it into sections" cacheName:nil];
[frc setDelegate:self];
[self setFetchedResultsController:frc];
[frc release];
frc = nil;
//Tells it to start.
[fetchedResultsController performFetch:nil];
Then for the table view delegate methods it is a piece of cake like so:
-(NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
return [[[fetchedResultsController sections] objectAtIndex:section] name];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView {
return [[fetchedResultsController sections] count];
}
- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section
{
return [[[fetchedResultsController sections] objectAtIndex: section] numberOfObjects];
}
/* If you want the bar on the right with the names of the sections...
-(NSArray*) sectionIndexTitlesForTableView:(UITableView *)tableView{
return [fetchedResultsController sectionIndexTitles];
}*/
-(UITableViewCell* )tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString* ident=#"cellident";
UITableViewCell *cell = [self.itemTable dequeueReusableCellWithIdentifier:ident];
if (!cell) {
cell = [[[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier:ident] autorelease];
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
- (void) configureCell:(UITableViewCell*)cell atIndexPath:(NSIndexPath*)indexPath {
NSManagedObject* item=[fetchedResultsController objectAtIndexPath:indexPath];
//set up your cell somehow
return cell;
}
You also need to add the delegate methods for the fetched results controller. They are all very simple and look something like this:
- (void)controllerWillChangeContent:(NSFetchedResultsController*)controller {
[tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController*) controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
NSIndexSet *set = [NSIndexSet indexSetWithIndex:sectionIndex];
switch(type) {
case NSFetchedResultsChangeInsert: [tableView insertSections:set withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteSections:set withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controller:(NSFetchedResultsController*)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath*)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath*)newIndexPath
{
UITableView *tv = tableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tv insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tv deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tv cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tv deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tv insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController*)controller {
[tableView endUpdates];
}
This will update the table if in some other part of the program a thing is added it will automatically show up on the table if the predicate matches.

NSFetchedResultsController index beyond bounds

I'm using an NSFetchedResultsController to display items in my table view:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [[self.fetchedResultsController fetchedObjects] count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"TagCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];;
}
Tag *tag = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = tag.name;
return cell;
}
However, this code breaks at this line:
Tag *tag = [self.fetchedResultsController objectAtIndexPath:indexPath];
With this message:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSCFArray objectAtIndex:]: index (0) beyond bounds (0)'
I've NSLogged [self.fetchedResultsController fetchedObjects] and I can confirm that there are indeed Tag objects. If I replace that above line with this everything works as expected:
Tag *tag = [[self.fetchedResultsController fetchedObjects] objectAtIndex:indexPath.row];
I NSLogged indexPath and the indexes are {0, 0} (section 0 row 0) so I know it isn't an issue with the section. I'm extremely confused as to why this is happening because theoretically, those two pieces of code do the same thing. Any help is appreciated.
Thanks
UPDATES:
id section = [[[self fetchedResultsController] sections] objectAtIndex:[indexPath section]];
NSLog(#"Section %#", section); <-- returns a valid section
This code results in the same exception: Tag *tag = [[section objects] objectAtIndex:[indexPath row];
If I NSLog [section objects] it returns an empty array. I'm not sure why [fetchedResultsController fetchedObjects] returns an array with the right objects, and [section objects] returns nothing. Does this mean that the objects I'm creating have no section? Here's the code that I use to add new objects:
- (void)newTagWithName:(NSString *)name
{
NSIndexPath *currentSelection = [self.tableView indexPathForSelectedRow];
if (currentSelection != nil) {
[self.tableView deselectRowAtIndexPath:currentSelection animated:NO];
}
NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity];
Tag *newTag = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:self.managedObjectContext];
// Configure new tag
newTag.name = name;
[self saveContext];
NSIndexPath *rowPath = [self.fetchedResultsController indexPathForObject:newTag];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:rowPath] withRowAnimation:UITableViewRowAnimationTop];
[self.tableView selectRowAtIndexPath:rowPath animated:YES scrollPosition:UITableViewScrollPositionTop];
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
}
And here's my saveContext method:
- (void)saveContext
{
// Save changes
NSError *error;
BOOL success = [self.managedObjectContext save:&error];
if (!success)
{
UIAlertView *errorAlert = [[[UIAlertView alloc] initWithTitle:#"Error encountered while saving." message:nil delegate:nil cancelButtonTitle:#"Dismiss" otherButtonTitles:nil] autorelease];
[errorAlert show];
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
}
}
Am I doing something wrong here?
I ran into the same problem. In my case, it seems to be a corrupt cache file. Try renaming your cache, or calling deleteCacheWithName:.
When you initialized your fetch request controller, you gave it a sectionNameKeyPath: even though your data has no sections. Then you hard coded your tables section number to 1.
The fetch request controller is trying to return an object at section index zero in a data structure that has no sections at all.
I reproduced your error in the default navigation template app by changing the sectionNameKeyPath from nil to the name of the entity's sole attribute.
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:#"timeStamp" cacheName:#"Root"];
... and then changed
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// return [[fetchedResultsController sections] count];
return 1;
}
and I get:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSCFArray objectAtIndex:]: index (0) beyond bounds (0)'
Set the sectionNameKeyPath:nil and that should fix your problem.
Are you compiling against, targeting or testing on 3.0?
What do you get back from the following code:
id section = [[[self fetchedResultsController] sections] objectAtIndex:[indexPath section]];
NSLog(#"Section %#", section);
Are you getting a valid section back?
If so, try adding the following line:
Tag *tag = [[section objects] objectAtIndex:[indexPath row];
If that produces an error then I suspect the issue is in your -tableView: numberOfRowsInSection: and that it may be giving back the wrong number of rows to the UITableView. Can you edit your question and post the code for that method as well?
Update
On further review I see where TechZen was pointing. You are telling the table view that you have one section when you may not. Further you are telling it how many objects your entire NSFetchedResultsController has when you should be answering it a little more succinctly.
Here is a slight change to your code.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[self fetchedResultsController sections] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[[self fetchedResultsController sections] objectAtIndex:section] numberOfObjects];
}
Make those changes and see what impact that has.
Question
What other UITableViewDataSource methods have you implemented? Sounds like there may be at least one more lingering error in your implementation.
got this error last night and it drove me crazy. I found that if you use the storyboard to specify the number of rows and sections, it needs to match the number you specify in your data source methods. To completely fix the error, you can set everything to 0 in the attributes inspector and just do it all programmatically, or just make sure that both data source methods and attributes inspector reflect the same amount of rows and sections.
^^

CoreData and UITableViewController Problem

I have a app that works with Core Data. The data has a field with a date and I would like to show every entry of a month in a seperate section.
How do I actually get the data ? I use a NSFetchedResultsController to get the data and use this :
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> sectionInfo = [[_fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
to get the rows and this :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyInfoObject *info = [_fetchedResultsController objectAtIndexPath:indexPath];
}
to get my actually data object.
Thanks
Make sure you set the sectionNameKeyPath when instantiating your fetchedResultsController
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:#"dateKey" cacheName:#"Root"];