10

我对使用 NSNumberFormatter 感到非常困惑。这应该很简单,但我无法让它工作。

我想设置一个 NSTextField 以允许输入十进制数字,可以带小数点或不带小数点。这是我认为可行的方法:

NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setMinimumFractionDigits:0];
[formatter setMaximumFractionDigits:4];
[formatter setAllowsFloats:YES];
[[timeFlowMultiplierTF cell] setFormatter:formatter];

但是,在文本字段中键入时,按小数点的“句点”键不会产生一个。输入“3.14”给我“314”。投入 [formatter setAlwaysShowsDecimalSeparator:YES] 最初将正确格式化数字,但如果我输入它,我再次无法输入小数点。

我在这里想念什么?你会认为这真的很简单

4

2 回答 2

12

我意识到这已经晚了大约 4 年,但我只是遇到了同样的胡说八道,并认为我会为后代分享问题所在(或可能是)。

事实证明,NSTextField 的所有值访问器(-objectValue-stringValue-doubleValue等)最终都调用了-validateEditing. -validateEditing反过来,使用 attachNSFormatter将编辑的文本转换为对象值,然后使用重新格式化的值重置字段中的文本

因此,如果您有任何代码在用户编辑它时监视该字段,并且您“偷看”该字段中的值,那么您会无意中重新格式化和重置文本字段中的文本。

并不是文本字段不允许您输入句点;那是文本字段中已经有“3”,当您输入句点时,文本将变为“3.”。如果您有一个动作/通知/委托方法,只要字段中的某些内容发生更改,就会运行,并且您调用任何类型的值方法,即“3”。格式化为“3”并更新单元格,删除您刚刚输入的句点。

我的技巧是避免使用 -类型的Value 方法并查看NSText对象以直接获取编辑后的文本,而无需触发-validateEditing

// some method that runs every time the field changes...
NSTextField* valueField = self.valueField;
NSNumberFormatter* fieldFormatter = valueField.formatter;
NSText* fieldEditor = valueField.currentEditor;
id newValue = ( fieldEditor!=nil ? [fieldFormatter numberFromString:fieldEditor.string] : valueField.objectValue );
于 2015-10-24T20:47:05.063 回答
1

感谢并遵循@James Bucanek 的回答:这是我在覆盖controlTextDidChange委托方法时使用的 Swift 实现,它阻止了用户输入小数点。它还会enabled根据是否存在有效(即 > 零和非零长度字符串)条目来更新界面上按钮的标志:

override func controlTextDidChange(notification: NSNotification) {
            if let formatter: NSNumberFormatter? = self.user_textfield.formatter as? NSNumberFormatter {
                if let field_editor: NSText = self.user_textfield.currentEditor() {
                    if let new_value: Float? = formatter!.numberFromString(field_editor.string!)?.floatValue {
                        self.my_button_out.enabled = new_value > 0.0
                    } else {
                        self.my_button_out.enabled = false
                    }
                }
            }
        }
于 2016-07-12T10:40:46.797 回答