【问题标题】:Validate longitude double value验证经度双精度值
【发布时间】:2018-01-26 10:48:03
【问题描述】:

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

也就是说,文本字段不应该接受无效值:为此,我使用 decimalPad 键盘,其中包含数字和十进制符号(在我的情况下,符号是 , ,而不是 .看起来这因地区而异)。

当用户编辑文本字段时,双精度值被传递给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
    }
}

测试文本字段中的值是否为双精度值。如果我插入一个逗号,它会认为该值是双倍的。如果我插入一个点,则值为 nil。

如何验证我的经度值?

【问题讨论】:

  • 试试这个:if let text = textField.text, let yourDouble = Double(text.replacingOccurrences(of: ",", with: ".")) { print(yourDouble) }
  • @AndreaMugnaini :当然可以,但是有没有办法知道哪个小数分隔符将使用键盘?这样我就可以只有逗号或只有点。显示一个点并让用户用逗号替换它很奇怪
  • 如果你想有更多的解释,你可以在这里查看:stackoverflow.com/q/30150829/2450755,你可能会喜欢这个答案:stackoverflow.com/a/44595112/2450755
  • @3000 别担心,不客气。
  • CLLocationCoordinate2DIsValid 返回一个布尔值,表示指定坐标是否有效。

标签: swift uitextfield double mapkit


【解决方案1】:

我为自己编写了这个函数,用于在触发文本字段的 didBeginEditing 委托方法时验证输入。此函数尝试从 String 生成有效的 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"
}

【讨论】:

    猜你喜欢
    • 2021-07-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-30
    • 1970-01-01
    • 2016-03-01
    • 2015-03-20
    • 2017-10-01
    相关资源
    最近更新 更多