使用绑定和格式化程序驯服NSTextField以正确运行

我想要一个窗口,需要接受一些用户输入,为此我有以下几点:

  • NSWindow使用NSWindowController从nib加载,也是它的代表
  • NSTextFieldNSNumberFormatter
  • 使用绑定, NSTextField绑定到NSWindowController的整数属性(为简单起见,我没有使用NSObjectController ,但可以根据需要添加它)
  • 用户在完成接受更改并关闭窗口时单击的'完成' NSButton
  • 在控制器的windowShouldClose:方法中做一个最终验证并决定我是否可以关闭窗口
  • 我想实现的非常简单,但Cocoa坚持要做到这一点具有挑战性:

  • NSTextField应该只接受一个数字作为它的最终值,它也大于零
  • 如果用户试图插入非数字值或零,应该有一个提示用户修改其条目的警报
  • 当用户点击完成时:
  • 做其他自定义验证(例如,比较一个数字是否比另一个好)
  • 如果这些值是正确的,请接受更改并关闭窗口(“模型”应该已经通过绑定更新了值)
  • 如果值不正确,应提示用户选择是否修复条目(使窗口保持打开状态)或关闭窗口并放弃更改
  • 够简单。 NSNumberFormatter应该已经覆盖了大部分任务,并且与绑定一起,这应该很容易实现。

    问题#1:

    NSTextField失去焦点并且该值对于更具描述性的内容不正确时,我无法找到更改在警报中显示给用户的错误消息的方法。 有没有办法做到这一点? 或者我需要以某种方式实现自己的NSFormatter?

    问题2:

    当用户更改NSTextField的值并单击“完成”按钮时,Cocoa不认为这是更新NSTextField绑定的模型的值的触发器。 这可能是标准的OSX行为,但是没有任何意义。

    我可以通过在'done'按钮的操作中调用[window makeFirstResponder:nil]来解决这个问题,以强制NSTextField失去焦点并更新值,但我想知道这是否是实现这个目标的正确方法。

    问题3:

    而这正是我真正挠挠我的地方。 如果用户在NSTextField输入了不正确的值(如非整数)并单击“完成”按钮,验证不会启动,并且NSTextField将在模型未更新时继续具有不正确的值。

    我期望“无效”警报仍然会显示,我有一些地方可以插入代码来决定是否关闭窗口,但我找不到任何方法来覆盖此行为。

    实现这些要求的标准做法应该是什么? 我是否应该放弃格式化程序和/或绑定,并仅使用操作手动完成所有操作?


    对于问题1,请尝试设置文本字段的委托并实现-control:didFailToFormatString:errorDescription:和可能的-control:didFailToValidatePartialString:errorDescription: 出示你想要的任何用户界面,使用错误描述或不使用。

    或者,您可以实现NSNumberFormatter的自定义子类并覆盖-getObjectValue:forString:errorDescription:-isPartialStringValid:proposedSelectedRange:originalString:originalSelectedRange:errorDescription: 你可以通过超级调用来实现大部分的实现。 如果失败,则可以替换super提供的错误描述。 如果您需要格式化程序对象(其属性等)的上下文来找出更好的错误描述,则可以使用此方法。

    问题2的正确解决方案是不以编程方式更改第一响应者。 相反,你应该确实使用NSObjectController在文本字段和窗口控制器之间进行调解。 在完成按钮的操作方法中,调用-commitEditing-commitEditingWithDelegate:didCommitSelector:contextInfo: NSObjectControllerNSController继承这些方法, NSController采用NSEditor协议。 当你得到结果时(前者异步,后者异步),则根据提交是成功还是失败,继续执行或不执行任何操作。

    我怀疑问题3也是以编程方式更改窗口的第一响应者的结果。 通常情况下,程序变更不会受到与用户操作相应的更改相同的检查。 例如,框架假定你,程序员知道你在做什么,所以将格式化程序的焦点更改转换为验证将是“错误的”。

    链接地址: http://www.djcxy.com/p/14929.html

    上一篇: Taming NSTextField with bindings and formatter to behave properly

    下一篇: Show Unicode characters in text field