简体   繁体   English

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

[英]Editing a TableView Cell with didSelectRowAtIndexPath Using Core Data

I have been following a few guides and questions on Stack Overflow, but not getting a desired result with basic table view editing. 我一直在关注一些有关堆栈溢出的指南和问题,但是在基本的表视图编辑中却没有得到理想的结果。

I have an app which is a table view controller. 我有一个应用程序,它是一个表视图控制器。 If I press the plus button, it brings up modally a view controller allowing me to add information to 4 text fields (and one date picker). 如果我按下加号按钮,它将以模态显示一个视图控制器,允许我向4个文本字段(和一个日期选择器)添加信息。 When I save it, it saves to Core Data and the Table View shows up the information. 当我保存它时,它保存到核心数据中,并且表视图显示了该信息。 I want to now simply be able to tap on a cell in the table view, be taken to another view controller and edit the cells if need be. 我现在想简单地能够在表格视图中点击一个单元格,将其带到另一个视图控制器并根据需要编辑单元格。 This view controller looks identical to the add view controller. 该视图控制器看起来与添加视图控制器相同。

Currently in the Detail view, it's not showing me the values in the textField and the NSLog comes back NULL. 当前在“详细信息”视图中,它没有显示textField中的值,并且NSLog返回NULL。

In the table view, I'm using NSFetchedResultsController to populate the information in the database and the NSManagedContext is as follows from the App Delegate: 在表视图中,我使用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 = CellforRow =

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

My didSelectRowAtIndexPath method is as follows: 我的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];
}

The DetailViewController has a property for the Information: DetailViewController具有信息的属性:

@property (nonatomic, strong) Information *selectedInformation; 

The viewDidLoad in the Detail looks like this: Detail中的viewDidLoad如下所示:

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

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

EDIT: Updated to include prepareForSegue 编辑:更新为包括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];
}

Which calls the setSelectedInformation: - (void)setSelectedInformation:(Information *)selectedInformation { self.title = self.selectedInformation.vendor; 调用setSelectedInformation的方法:-(void)setSelectedInformation:(Information *)selectedInformation {self.title = self.selectedInformation.vendor;

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

} }

I'm not running with both didSelectRow and prepareForSegue, it's one or the other, but both give the same results. 我没有同时使用didSelectRow和prepareForSegue,它们是一个或另一个,但是两者给出的结果相同。

The NSLog is giving me NULL and when the view controller does come on screen, it does not have any information in that field. NSLog给了我NULL,并且当视图控制器确实出现在屏幕上时,该字段中没有任何信息。

I segued to this new view controller in storyboard, so I'm not sure if I should be using prepareForSegue, but that did not work either. 我在情节提要中锁定了这个新的视图控制器,因此不确定是否应该使用prepareForSegue,但这也不起作用。

My question is - do I need to do some sort of fetch in the DetailViewController into Core Data? 我的问题是-我需要在DetailViewController中进行某种类型的提取到Core Data吗?

What do I need to do to get this to work? 我需要做什么才能使它正常工作?

Thanks! 谢谢!

If you're using storyBoards you should definitely make your information transition in the prepareForSegue method since the storyBoard will itself instantiate your view controller. 如果您使用的是StoryBoards,则一定要在prepareForSegue方法中进行信息转换,因为storyBoard本身将实例化视图控制器。

In your didSelect method : 在您的didSelect方法中:

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

} }

In your prepareForSegue method : 在您的prepareForSegue方法中:

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

That should do it ! 那应该做!

Your 2 approaches each have different issues: 您的2种方法各有不同的问题:

When you use didDeselectRowAtIndexPath and viewDidLoad , your problem is that you're creating a view controller that is never placed on screen (because a different one is created by the segue). 当您使用didDeselectRowAtIndexPathviewDidLoad ,您的问题是您正在创建一个永远不会出现在屏幕上的视图控制器(因为segue创建了一个不同的视图控制器)。

When you use prepareForSegue , your problem is that you call setSelectedInformation and it immediately tries to interact with editingNameField and this doesn't exist yet (because the view hasn't been loaded). 当您使用prepareForSegue ,您的问题是调用setSelectedInformation ,它立即尝试与editingNameField进行交互,并且该交互尚不存在(因为尚未加载视图)。

So, you should be using prepareForSegue , but you also need to use the viewDidLoad . 因此,您应该使用prepareForSegue ,但是还需要使用viewDidLoad Set the information to the destination view controller. 将信息设置到目标视图控制器。 In the destination, apply that data to the view when it has been loaded. 在目标中,将数据加载到视图后将其应用于视图。

Finally, from a debugging point of view - log the source data, not just the result. 最后,从调试的角度来看-记录源数据,而不仅仅是结果。 This will lead you towards the source of the issue. 这将引导您找到问题的根源。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM