问题
I´m having some problems when saving data in core data and also with the rows organization and for better understanding of what my problem is, i´m going to explain what i have:
I have a main tableview working with dynamic rows, in this tableview i have a + button, whenever the + button is pressed, a tableview appears inside a popover were the user can choose the "type of cell" to insert in the main tableview. The "type of cell" are custom cells and they have they´re one class and xib file. Each custom cell has various textfields...so the idea is:
- choose a type of cell and insert in the main tableview.
- fill the textfields with data.
- the data saved corresponds to the number of rows inserted and the data in the textfields.
When calling the popover tableview i have this method in my main tableview:
- (IBAction)Add:(id)sender
{
SelectProduct *typeProduct=[[self.storyboard instantiateViewControllerWithIdentifier:@"selectTable"]initWithTableViewTag:self.tableView.tag];
self.popover=[[UIPopoverController alloc]initWithContentViewController:typeProduct];
[popover presentPopoverFromBarButtonItem:buttonAdd permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
typeProduct.popView = self.popover;
typeProduct.cellSelected = self.cellSelected; //cellSelected is core data subclass.
typeProduct.delegate = self;
typeProduct.managedObjectContext = self.managedObjectContext;
}
then in my didSelectRow of my popover tableview, i have:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
row = indexPath.row;
if (row == 0)
{
cellSelected=[NSEntityDescription insertNewObjectForEntityForName:@"CellSave" inManagedObjectContext:self.managedObjectContext];
cellSelected.nameCellData = @"Olive";
cellSelected.amountData = myCostumCell.amount.text;
}
From here, a cell is inserted in my main tableview, here´s my main tableview relevant methods:
- (void)viewDidLoad
{
[self.tableView registerNib:[UINib nibWithNibName:@"myCostumCellXib" bundle:nil] forCellReuseIdentifier:@"myCostumCell"];
AppDelegate *appDelegate =[[UIApplication sharedApplication] delegate];
self.managedObjectContext=[appDelegate managedObjectContext];
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error])
{
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
[self fetchedResultsController];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"myCostumCell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.cellSelected = self.cellSelected;
cell.managedObjectContext = self.managedObjectContext;
if (cell == nil)
{
cell = [[MyCostumCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cellSelected = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.nameCell.text = cellSelected.nameCellData;
if ([cellSelected.nameCellData isEqualToString:@"Olive"])
{
cell.amount.text = cellSelected.amountData;
// i have more textfields to assign but i think you understand the rest..
}
}
My fetchedResultsController method: ( also have the others but they are the standard stuff)
- (NSFetchedResultsController *)fetchedResultsController
{
if (_fetchedResultsController != nil)
{
return _fetchedResultsController;
}
// Create and configure a fetch request.
NSFetchRequest *fetchRequestCellSave = [[NSFetchRequest alloc] init];
NSEntityDescription *entityCellSave=
[NSEntityDescription entityForName:@"CellSave" inManagedObjectContext:self.managedObjectContext];
[fetchRequestCellSave setEntity:entityCellSave];
// Create the sort descriptors array.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"nameCellData" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequestCellSave setSortDescriptors:sortDescriptors];
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequestCellSave managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"nameCellData" cacheName:nil];
_fetchedResultsController.delegate = self;
self.fetchedResultsController = _fetchedResultsController;
return _fetchedResultsController;
}
Now if i want to exit the main tableview and go to another tableview, i understand that i have to save the content of the textfields in my managedObject, so:
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
cellSelected.amountData = cell.amount.text;
//i have more textfields to assign but for the example i think you understand
what i want.
[self.managedObjectContext save:nil];
}
From here, one row is "saved" and the text in the amount also...but the problems start when i add one more row:
Why the new row appears on top of the tableview, instead of after the previous row inserted?
When i fill the textField (amount) of the second row inserted...exit the tableview and come back...the textfield doesn´t appears filled..What am i doing wrong?
The previous issue happens if i insert 2 rows at once, but if i insert one...exit the tableview and then come back and insert another row...the textfield amount is saved...
Where´s my problem? is it in my custom cell class? Where?...I´m sorry for the long post, but this is driving me crazy...
thanks for your time
Regards
回答1:
You need to save the data as soon as it is entered, not just when the view is removed from display. As soon as a cell is scrolled off screen it will be reused or killed so you have to save your text before that happens. Best place is in the text field delegate callback when the text is changed.
When you add 2 rows before saving you have corrupted your internal state (when the second row is added but you haven't yet saved the data from the first row).
Your rows are sorted by entered text so it depends on the text (or lack of) to determine where it appears on screen.
You probably shouldn't be giving the cell a reference to the managed object context (not MVC).
You should also think about the difference between local and instance variables as your code seems to confuse them...
来源:https://stackoverflow.com/questions/16157190/core-data-inserting-rows-and-saving-issue