强制NSTextField仅接受十进制(#。#)数字和句点

时间:2017-01-11 01:01:27

标签: swift3 nstextfield nscharacterset

我正在尝试将其设为NSTextField,只接受Mac应用中的12.43.6等数字和句点。

在审查其他SO问题后,我觉得自己变得非常接近,但我无法理解。以下代码有效,但不允许.个字符。当我输入true 时,它会返回.并且不会发出嘟嘟声,但它不会让字符显示在字段中

class decimalFormatter: NumberFormatter {

  override func isPartialStringValid(_ partialString: String, newEditingString newString: AutoreleasingUnsafeMutablePointer<NSString?>?, errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>?) -> Bool {

    //Allows the text to be deleted
    if partialString.isEmpty {
      return true
    }

    //Check for #.# numbers
    let charSet = NSCharacterSet(charactersIn: "1234567890.").inverted

    if partialString.rangeOfCharacter(from: charSet) != nil{
      NSBeep()
      return false
    }else{
      return true
    }

  }
}

知道我做错了吗?

2 个答案:

答案 0 :(得分:2)

我找到了一种更简单的方法。在controlTextDidChange里面我刚刚这样做了:

let charSet = NSCharacterSet(charactersIn: "1234567890.").inverted
let chars = fieldDuration.stringValue.components(separatedBy: charSet)
fieldDuration.stringValue = chars.joined()

效果很好!

答案 1 :(得分:0)

@Clifton Labrum解决方案确实很棒,但它不会将字段减小为十进制(#。#),您可以将1.2.4输入一些内容,这将导致尝试将其投射到Float时出错。

以下是对我来说效果很好的扩展的草案(在Swift 4 中)

public override func controlTextDidChange(_ obj: Notification) {
    if let textfield = obj.object as? NSTextField,
        textfield == self.quantityTextField {

        var stringValue = textfield.stringValue

        // First step : Only '1234567890.' - @Clifton Labrum solution
        let charSet = NSCharacterSet(charactersIn: "1234567890.").inverted
        let chars = stringValue.components(separatedBy: charSet)
        stringValue = chars.joined()

        // Second step : only one '.'
        let comma = NSCharacterSet(charactersIn: ".")
        let chuncks = stringValue.components(separatedBy: comma as CharacterSet)
        switch chuncks.count {
        case 0:
            stringValue = ""
        case 1:
            stringValue = "\(chuncks[0])"
        default:
            stringValue = "\(chuncks[0]).\(chuncks[1])"
        }

        // replace string
        textfield.stringValue = stringValue

    }
}

这可以防止.的多次出现,即使我知道这不是执行此操作的最佳算法。例如,1.2.4粘贴后将变成1.2,并且通过键盘您无法添加其他.