使用核心数据使用didSelectRowAtIndexPath编辑TableView单元格

时间:2013-11-28 15:33:40

标签: ios objective-c uitableview core-data didselectrowatindexpath

我一直在关注Stack Overflow上的一些指南和问题,但没有通过基本的表视图编辑获得所需的结果。

我有一个应用程序,它是一个表视图控制器。如果我按加号按钮,它会以模态方式显示一个视图控制器,允许我向4个文本字段(和一个日期选择器)添加信息。当我保存它时,它会保存到Core Data,而Table View会显示信息。我现在想简单地点击表视图中的单元格,将其带到另一个视图控制器并根据需要编辑单元格。此视图控制器看起来与添加视图控制器相同。

目前在详细信息视图中,它没有显示textField中的值,NSLog返回NULL。

在表视图中,我使用NSFetchedResultsController来填充数据库中的信息,NSManagedContext如下所示:来自App Delegate:

- (NSManagedObjectContext *)managedObjectContext
{
    NSManagedObjectContext *context = nil;
    id delegate = [[UIApplication sharedApplication] delegate];
    if ([delegate performSelector:@selector(managedObjectContext)])
    {
        context = [delegate managedObjectContext];
    }
    return context;
}

- (NSFetchedResultsController *)fetchedResultsController
{
    NSManagedObjectContext *managedObjectContext = [self managedObjectContext];

    if (_fetchedResultsController != nil)
    {
        return _fetchedResultsController;
    }

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Information" inManagedObjectContext:managedObjectContext];
    fetchRequest.entity = entity;
    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"date.historyDate" ascending:NO];
    fetchRequest.sortDescriptors = [NSArray arrayWithObject:sort];
    NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:@"date.historyDate" cacheName:nil];
    self.fetchedResultsController = theFetchedResultsController;
    _fetchedResultsController.delegate = self;
    return _fetchedResultsController;
}

CellforRow =

cell.textLabel.text = information.vendor;
cell.detailTextLabel.text = information.type; 

我的didSelectRowAtIndexPath方法如下:

- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{

    DetailViewController *detailViewController = [[DetailViewController alloc] init];
    Information *selectedInformation = [self.fetchedResultsController objectAtIndexPath:indexPath];
    detailViewController.selectedInformation = selectedInformation;     
    [self.navigationController pushViewController:detailViewController animated:YES];
}

DetailViewController具有Information:

的属性
@property (nonatomic, strong) Information *selectedInformation; 

详细信息中的viewDidLoad如下所示:

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.title = self.selectedInformation.vendor;
    self.editingNameField.text = self.selectedInformation.vendor;

    NSLog(@"%@", self.editingNameField.text);
}

编辑:已更新,包括prepareForSegue

NSIndexPath *indexPath = [self.timelineTableView indexPathForCell:sender];
Information *selectedInformation = [self.fetchedResultsController objectAtIndexPath:indexPath];
if ([segue.identifier isEqualToString:@"Editable Cell"])
{
    DetailViewController *selectedInformationTVC = [segue destinationViewController];

    [selectedInformationTVC setSelectedInformation:selectedInformation];
}

调用setSelectedInformation: - (void)setSelectedInformation :(信息*)selectedInformation {     self.title = self.selectedInformation.vendor;

self.editingNameField.text = self.selectedInformation.vendor;
NSLog(@"%@", self.editingNameField.text);

}

我没有同时运行didSelectRow和prepareForSegue,它是一个或另一个,但两者都给出了相同的结果。

NSLog给我NULL,当视图控制器出现在屏幕上时,它在该字段中没有任何信息。

我在故事板中搜索这个新的视图控制器,所以我不确定我是否应该使用prepareForSegue,但这也不起作用。

我的问题是 - 我是否需要在DetailViewController中对Core Data进行某种提取?

我需要做些什么才能让它发挥作用?

谢谢!

2 个答案:

答案 0 :(得分:1)

如果您正在使用storyBoards,那么您绝对应该使用prepareForSegue方法进行信息转换,因为storyBoard本身会实例化您的视图控制器。

didSelect方法中:

- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
    Information *information = [self.fetchedResultsController objectAtIndexPath:indexPath];
    // Save your selected information for later
    self.selectedInformation = information;

}

prepareForSegue方法中:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"DetailViewSegue"])
    {
        DetailViewController *dvc = (DetailViewController *)segue.destinationViewController;
        dvc.selectedInformation = self.selectedInformation;
    }
}

应该这样做!

答案 1 :(得分:1)

你的两种方法各有不同的问题:

当您使用didDeselectRowAtIndexPathviewDidLoad时,您的问题是您正在创建一个从未放置在屏幕上的视图控制器(因为segue创建了另一个视图控制器)。

当您使用prepareForSegue时,问题是您调用setSelectedInformation并立即尝试与editingNameField进行交互,但这还不存在(因为视图尚未显示)加载)。

因此,您应该使用prepareForSegue,但您还需要使用viewDidLoad。将信息设置为目标视图控制器。在目标中,在加载时将该数据应用于视图。

最后,从调试的角度来看 - 记录源数据,而不仅仅是结果。这将引导您找到问题的根源。