我在核心数据中保存数据时遇到了一些问题,并且还有行组织,为了更好地理解我的问题,我将解释我的内容:
我有一个使用动态行的主tableview,在这个tableview中我有一个按钮,每当按下按钮时,弹出框内会出现一个tableview,用户可以选择要在主tableview中插入的“单元格类型” . “单元格类型”是自定义单元格,它们有一个类和xib文件 . 每个自定义单元格都有各种文本字段...所以这个想法是:
-
选择一种单元格并插入主tableview中 .
-
用文本填充文本字段 .
-
保存的数据对应于插入的行数和文本字段中的数据 .
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;
}
现在,如果我想退出主tableview并转到另一个tableview,我明白我必须在我的managedObject中保存文本字段的内容,所以:
- (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];
}
从这里开始,“保存”一行,数量中的文本也是......但是当我再添加一行时问题就开始了:
-
为什么新行显示在tableview的顶部,而不是在插入上一行之后?
-
当我填写插入的第二行的textField(金额)时...退出tableview并返回...文本字段没有显示填充..我做错了什么?
-
如果我一次插入2行,则会发生上一个问题,但如果我插入一个...退出tableview然后返回并插入另一行...文本字段数量已保存...
我的问题在哪里?它是我的自定义单元类吗?在哪里?...我很抱歉长篇文章,但这让我发疯...
谢谢你的时间
问候
1 回答
您需要在输入数据后立即保存数据,而不仅仅是在从显示中删除视图时 . 一旦单元格在屏幕上滚动,它将被重用或杀死,因此您必须在发生之前保存文本 . 更改文本时,最佳位置是文本字段委托回调 .
在保存之前添加2行时,您的内部状态已损坏(添加第二行但尚未保存第一行的数据时) .
您的行按输入的文本排序,因此它取决于文本(或缺少)以确定它在屏幕上的显示位置 .
您可能不应该为单元格提供对托管对象上下文(而不是MVC)的引用 .
您还应该考虑本地变量和实例变量之间的区别,因为您的代码似乎会混淆它们......