使用表格视图编辑核心数据中单个属性的正确方法

Posted

技术标签:

【中文标题】使用表格视图编辑核心数据中单个属性的正确方法【英文标题】:The Right Way to Edit Single Attributes Inside Core Data using a Table View 【发布时间】:2013-12-11 17:14:37 【问题描述】:

我有一个简单的应用程序,它由一个表格视图和一个加号按钮组成,用户可以模态地转到另一个视图控制器,在文本字段中添加一些文本并保存它。

将它保存在后端意味着保存到 Core Data,然后使用 NSFetchedResultsController 将其显示到表视图控制器。

型号是:

交易实体 日期实体 场合实体 人物实体

事务实体与其他实体有关系,因此 Person 的 NAME 属性将是 whoFrom.name。

添加新条目时一切正常,但在编辑时我被卡住了。我单击一个单元格并通过 prepareForSegue 设置视图控制器中的信息。名称文本字段具有输入的名称,事件文本字段具有输入的名称。

我希望能够干净地编辑它。

因此,如果用户将名称文本字段从 Jack 更改为 Bill,我希望它仅针对此单元格进行更改,而不是将每个 jack 更改为 bill。

所以要遵循以下逻辑:

将姓名从 Jack 更改为 Bill 如果 Bill 存在,则返回并将此交易添加到 Bill 的交易中 如果比尔不存在,则创建它。 如果 Jack 只有一个事务并且我将 Jack 重命名为 Bill,请确保从 Core Data 中删除“Jack”。

在保存新条目时,我已经有 1 和 2 的代码。

NSManagedObjectContext *context = [self managedObjectContext];
Transaction *transaction = [NSEntityDescription insertNewObjectForEntityForName:@"Transaction" inManagedObjectContext:context];

Person *enteredPerson = (Person *)[Person personWithName:self.nameTextField.text inManagedObjectContext:context];
transaction.whoBy = enteredPerson;

personWithName 是 Person NSManagedObjectSubclass 上的一个类别:

+ (Person *)personWithName:(NSString *)name inManagedObjectContext:(NSManagedObjectContext *)context

    Person *person = nil;

    // Creating a fetch request to check whether the name of the person already exists
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Person"];
    request.predicate = [NSPredicate predicateWithFormat:@"name = %@", name];
    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
    request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];

    NSError *error = nil;
    NSArray *people = [context executeFetchRequest:request error:&error];
    if (!people)
    
        // Handle Error
    
    else if (![people count])
    
        // If the person count is 0 then let's create it
        person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:context];
        person.name = name;
    
    else
    
        // If the object exists, just return the last object .
        person = [people lastObject];
    
    return person; 

我一直在阅读教程并思考如何在我的编辑视图控制器或通常称为细节视图控制器的“保存”方法中执行此操作,但我只是不知道如何使其工作。

通过编辑,我不想创建新交易,我只想获取该交易的信息,更改名称或事件并再次保存。所以我无法想象我会将 insertNewObject 放入 DetailViewController 的保存方法中。

我是否分配一个新名称和一个旧名称,是否更新 transaction.whoBy 等?

我真的迷失了这个方向,所以任何朝着正确方向的推动都会非常有帮助;我知道我已经接近了,因为我上面用于添加新条目的保存方法已经成功地完成了返回用户(如果他存在)或创建一个用户(如果他不存在)的逻辑。

谢谢,

【问题讨论】:

【参考方案1】:

其实很简单。您的 person 实例要么存在,要么不存在。如果是,向用户显示一个列表,他可以在其中选择要编辑的人。如果是新人,允许用户显式创建新人。

如果用户尝试使用已存在的名称创建新用户,请询问用户该怎么做。

从视图控制器的角度来看,这很容易。您可以使用相同的控制器进行编辑和创建。只需给它一个Person 类型的@property 并简单地更改属性,例如名称。如果是编辑分配选定的人,如果不是创建一个并分配它。如果是新的并且用户取消,则删除该对象。

【讨论】:

谢谢@Mundi - 这很有意义,我基本上已经开始工作了 - 我不确定这是否是另一个问题(如果是,我会很高兴地问它)但是我有一个完全基于“人员”的选项卡,它只显示名称。当我从第一个表格视图(根据问题)编辑单元格时,它运行良好,但它不会删除旧用户名,如果它只有一个条目.. 示例.. John 有一个条目.. 我将 John 重命名为 Bill,它创建了 Bill,其中包含所有信息,但它也保留了 John.. 在这个阶段,John 现在应该被删除..我希望这是有道理的! 或者删除不是正确的词..但由于约翰没有任何交易,他不应该出现在姓名列表中.. 名称控制器应该使用样板回调实现来实现 NSFetchedResultsControllerDelegate。然后约翰将“自动”成为比尔。

以上是关于使用表格视图编辑核心数据中单个属性的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

在不使用表视图的情况下更新核心数据属性

带有核心数据的可编辑表格视图

在表格视图部分中对核心数据对象进行排序

根据日期添加核心数据属性

Qt 中具有单个模型的表格和列表视图

TabBar 项目 - 表格视图中的核心数据