验证经度双值

时间:2018-01-26 10:48:03

标签: swift uitextfield double mapkit

我有一个UITextField:它的文字是经度(双)值。我的设备使用点打印此双精度,例如24.000000(而不是24,00000)。

也就是说,文本字段不应该接受无效值:为此,我使用decimalPad键盘,其中包含数字和小数符号(在我的例子中,符号为,,不是.但看起来根据区域设置而有所不同。)

当用户编辑文本字段时,double值将传递给MapKit映射,因此在传递之前该值必须有效。

纬度值的有效性非常明确(value>-90value<90),但我不知道如何将字符串转换为有效的双精度。

首先,就我而言,初始数据来自:

mapView.convert(touchPoint, toCoordinateFrom: mapView)

这个带点返回坐标,并在文本域中显示该坐标。

第二:如果用户正在编辑文本字段,他可以删除一个点,但他不能再插入它。它的点应该用逗号替换,因为在十进制小键盘中我只有一个逗号。

第三次:我试过这个扩展程序:

extension String {
    struct NumFormatter {
        static let instance = NumberFormatter()
    }

    var doubleValue: Double? {
        return NumFormatter.instance.number(from: self)?.doubleValue
    }
}

测试文本字段中的值是否为double。如果我插入逗号,它会将值视为double。如果我插入一个点,则值为nil。

如何验证我的经度值?

1 个答案:

答案 0 :(得分:0)

我自己编写了此函数,以在触发文本字段的didBeginEditing委托方法时验证输入。此函数尝试从字符串生成有效的Double数字,或将返回默认值。

完成编辑后,didFinishEditing委托方法可以确保数字不以小数点结尾,从而输出为“ 10”。会是“ 10”,但我自己会处理不同的部分。

您将需要根据自己的目的更改功能或小数点字符或小数位数。对于我而言,每次更改文本字段中的值时,都会对文本进行验证和处理,以确保用户在输入文本字段时不会输入无效的输入。

private func validate(from text: String?) -> String {
    guard var text = text else { return "1.0" }  // makes sure the textfield.text is not nil
    guard text.first != "." else { return "0." } // prevents entering ".0"

    text = text.filter{ CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: $0.description)) || $0 == "." } // makes sure the entered text is only digits or "." otherwise removes the non digit characters
    let integerPart = String(text[text.startIndex..<(text.index(of: ".") ?? text.endIndex)]) // it is the digits before the first decimal point
    var decimalPlaces = "" // digits after the decimal point
    var afterIntegerText = "" // the text after the integer number before the decimal point
    if let decimalPointIndex = text.index(of: ".") { // if the number has a decimal point
        afterIntegerText = String(text[decimalPointIndex..<text.endIndex]) // "10.12345 will result become ".12345"
        decimalPlaces = String(afterIntegerText.replacingOccurrences(of: ".", with: "").prefix(2)) // ".12345" will become "12"
        decimalPlaces = afterIntegerText.isEmpty ? "" : ".\(decimalPlaces)" // generates the text of decimal place character and the numbers if any
    }
    return "\(integerPart + decimalPlaces)" // "10.*$1.2." will become "10.12"
}