【问题标题】:Tableview updates values in the twilight zoneTableview 更新暮光区中的值
【发布时间】:2019-12-02 01:33:25
【问题描述】:

我已关注this tutorial 并成功将我的NSTableView 绑定到核心数据实体。

表格是一个基于视图的单元格,完全由核心数据实体填充。

我将+- 按钮绑定到NSArrayController。当我按下加号按钮时,一条新记录被添加到核心数据并出现在表中,当我选择一个条目并按下减号时,该记录将从数据库中删除。就此而言,我已经为添加/删除键覆盖了此代码。

  @IBAction override func add(_ sender: (Any)?) {
    let newApp = self.newObject() as AnyObject
    newApp.setValue("New Entry", forKey: "name")
    self.addObject(newApp as Any)
  }

  @IBAction override func remove(_ sender: (Any)?) {
    // Do certain stuff before removing all selected rows
    self.remove(atArrangedObjectIndexes: self.tableView!.selectedRowIndexes)
  }

我使表格视图单元格可编辑。当按下加号按钮时,会创建一个新条目并在表格中显示“新条目”文本。这个新条目创建了一个核心数据记录。我们就叫它record 1吧。

现在我希望用户使用他们想要的名称编辑条目。

所以我选择了新的单元格并按回车键。该单元格现在处于编辑模式。 我在该单元格中键入我想要的新名称,该名称将传递给核心数据实体。

例如,我键入 BONOBO,然后按 ENTER。

此表必须只包含唯一名称。因此,一旦按下 ENTER 并且单元格结束编辑,我想检查核心数据以查看名称 BONOBO 是否已被占用,如果是,则拒绝该名称并告诉用户提供一个新名称。

这是问题所在:当我按下 ENTER 时,record 1 立即将其名称从 New Entry 更改为 BONOBO,然后我才能检查数据库中是否已存在该条目,这意味着我所做的任何检查,总是会告诉我记录存在。事实上,该记录存在于内存中,因为尚未保存上下文。

我通过将所有单元格的委托设置为一个类并使用其委托方法controlTextDidEndEditing(_ obj: Notification)来拦截输入。

我也尝试为文本字段设置一个操作,但问题是一样的。

如何在核心数据发生变化之前进行拦截?

【问题讨论】:

    标签: macos cocoa core-data nstableview nstablecellview


    【解决方案1】:

    这里的技巧是利用键值编码的内置验证方法。见Object Validation

    我从未对托管对象进行过此操作,但该过程似乎与常规 KVC 验证相同。你想实现一个名称为:

    validate<Key>:error:
    

    ... 其中“Key”是您要验证的参数的名称。这需要一个指向您要验证的值的指针,另一个指向一个 NSError 对象。在方法内部测试传入的值是否可接受。您可以返回 true 以接受它,修改值并返回 true 以接受修改后的版本,或返回 false 以彻底拒绝它(修改错误对象以将某些内容发送回用户)。

    【讨论】:

    • 警告:这些方法将验证一切。不仅是用户所做的更改,还有代码中的更改。
    • 不幸的是,这不适用于与该问题相关的特定问题。如果我插入一条新记录,这可行,但如果我使用我在问题中提到的 add: 方法、validateForInsert 或其他从未调用过的方法。
    • 我不确定你在说什么。上面的add: 例程似乎创建了一个名为“新条目”的空占位符对象。如果您已成功将该空对象添加到 arrayController 的排列对象中,它应该会自动响应 KVC 并在用户编辑名称时调用验证例程。它不会在“新条目”上调用验证,因为它是在您将其连接到排列对象之前设置的。
    • 如果您想在上述例程中进行验证,则在 newApp.setValue() 行之前,添加 validateValue(_:forKey:) 语句。抱歉,我的 swift 语法可能有误——我习惯了 objC——但我猜这看起来像 validateValue("New Entry":forKey:"name")。此行显式调用您在其他地方创建的validateName() 方法。
    猜你喜欢
    • 2019-12-12
    • 2016-10-18
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多