添加编辑行为绑定NSFormCell
我有一个带有客户 ID 属性的核心数据模型类。它绑定到表单单元格。当用户完成编辑文本时,我希望有机会将其输入内容转换为大写,使用取决于旧值和新值的逻辑。
理想情况下,我希望使用可以在笔尖中实例化的对象并连接到文本单元格,使行为保持靠近其所属的视图。但我会选择一个必须连接到模型的物体。
我已经实现了这三种不同的方式:
- 模型类中的自定义 setter 方法
- 文本编辑委托实现
NSControlTextEditingDelegate
- 使用 KVO 来通知更改并启动后续更改的帮助器类
所有三种实现都有问题。分别存在的问题:
- 此行为不属于模型。例如,我应该能够在代码中设置该属性,而无需触发它。
- 我无法获取“之前”值,因为表单单元格不提供
controlTextDidBeginEditing:
调用(并且在调用controlTextDidEndEditing:
时旧值已消失) 。此外,在不输入任何内容的情况下进出字段会触发对controlTextDidEndEditing:
的调用。 - 当针对用户的更改触发观察,并且我启动对该属性的后续更改时,视图会忽略更改通知并且不会重绘。 (我认为绑定器这样做是为了提高效率。通常在更新模型时,它可以忽略正在更新的字段中的 KVO 观察结果。)
您将如何解决这个问题?
I've a Core Data model class with a customer ID attribute. It's bound to a form cell. When the user finishes editing the text I want a chance to convert their entry to upper case, using logic which depends on the old and new values.
Ideally I want to keep the behavior close to the view where it belongs, using an object I can instantiate in the nib and hook up to the text cells. But I'd settle for an object I had to hook up to the model.
I've implemented this three different ways:
- Custom setter method in the model class
- Text editing delegate implementing
NSControlTextEditingDelegate
- Helper class which uses KVO to notice the change and initiate a subsequent change
All three implementations have problems. The issues, respectively:
- This behavior doesn't belong in the model. I should be able to set the attribute in code, for example, without triggering it.
- I can't get the "before" value because the form cell doesn't provide
controlTextDidBeginEditing:
calls (and the old value is gone by the timecontrolTextDidEndEditing:
is called). Furthermore tabbing in and out of the field without typing anything triggers a call tocontrolTextDidEndEditing:
. - When the observation fires for the user's change, and I initiate a subsequent change to that property, the view ignores the change notification and doesn't redraw. (I presume the binder does this for efficiency. Normally when updating the model, it can ignore the KVO observations from the field being updated.)
How would you solve this problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
之后,听起来有一些可能的方法:
我尝试了两者。更多问题:
editWithFrame:inView:editor:delegate:event:
并不总是在输入字段时调用,因此很难访问endEditing:
中的旧值。新的解决方案是对我原来的 #2 的改进:文本编辑委托实现
NSControlTextEditingDelegate
。仅实现
control:textShouldEndEditing:
,而不是controlTextDidBeginEditing:
和controlTextDidEndEditing:
。在该方法中,如有必要,操作文本,然后返回 YES。我在笔尖中实例化它并使其成为表单的委托(而不是单元格的委托)。在下面的代码中,我使用
infoForBinding:
获取旧值,但如果您不使用绑定,则可以向模型对象添加一个出口。After some discussion here, it sounds like some possible ways to do tho:
I tried both. More issues:
editWithFrame:inView:editor:delegate:event:
isn't always called upon entering a field, so it's difficult to access the old value inendEditing:
.New solution is a refinement on my original #2: text editing delegate implementing
NSControlTextEditingDelegate
.Instead of
controlTextDidBeginEditing:
andcontrolTextDidEndEditing:
, implement onlycontrol:textShouldEndEditing:
. In that method, manipulate the text if necessary, then return YES.I instantiate this in the nib and make it the form's delegate (not the cells'). In the code below I get the old value using
infoForBinding:
but if you aren't using bindings, you could add an outlet to the model object instead.