Ios UITextField';s数字键盘:浮点值用点代替逗号

Ios UITextField';s数字键盘:浮点值用点代替逗号,ios,swift,uitextfield,Ios,Swift,Uitextfield,我使用的是从数字键盘填充的文本字段 问题是,对于许多本地区域格式(例如,所有欧洲格式),UITextField的数字键盘上都有逗号而不是圆点,因此每次我写十进制数时,UITextField都无法识别十进制逗号和它的整数;例如23,07变成23 我怎样才能解决这个问题? 我想把textField设置在美国;可能吗?怎么做 我使用以下方法读取值: var importo = (importoPrevistoTF.text as NSString).floatValue 的潜在副本,请使用NSNum

我使用的是从数字键盘填充的文本字段

问题是,对于许多本地区域格式(例如,所有欧洲格式),UITextField的数字键盘上都有逗号而不是圆点,因此每次我写十进制数时,UITextField都无法识别十进制逗号和它的整数;例如23,07变成23

我怎样才能解决这个问题? 我想把textField设置在美国;可能吗?怎么做

我使用以下方法读取值:

var importo = (importoPrevistoTF.text as NSString).floatValue

的潜在副本,请使用
NSNumberFormatter

示例Swift:

let number = NSNumberFormatter().numberFromString(numberString)
if let number = number {
    let floatValue = Float(number)
}
示例(目标C):


它可能是的副本,但由于原始版本为Objective-C,因此这里有一个快速版本:

let label = "23,07"
let formatter = NSNumberFormatter()
let maybeNumber = formatter.numberFromString(label)
if let number = maybeNumber {
    println(number)   // 23.07
}

没有人真正直接解决这个问题

也就是说,十进制分隔符是区域设置的约定

iOS支持基于特定区域设置格式化数字

如果您纯粹是在给定的环境中工作,那么一切都应该正常工作。键盘应接受带有正确小数分隔符的数字

例如,如果你在欧洲的大多数国家,你会输入一个逗号作为小数点分隔符。在这些国家输入点是错误的。其中一个国家的人不会这样做,因为它是错误的小数分隔符。欧洲用户将知道使用逗号作为十进制分隔符,而您无需执行任何操作

如果你在美国,你会用句号。在美国使用逗号是错误的

显示十进制数字的方式是使用数字格式化程序。创建数字格式化程序时,默认情况下它使用当前区域设置

如果需要将包含十进制数的字符串从一个区域设置转换为另一个区域设置,则应使用2个数字格式化程序。在源语言环境中使用格式化程序将字符串转换为浮点。然后使用带有目标语言环境的格式化程序将数字转换为输出格式的字符串


只需在默认的当前语言环境中创建一个数字格式化程序,然后创建第二个数字格式化程序,并将其语言环境显式设置为要使用的其他语言环境。

Swift 4

extension String {
    static let numberFormatter = NumberFormatter()
    var doubleValue: Double {
        String.numberFormatter.decimalSeparator = "."
        if let result =  String.numberFormatter.number(from: self) {
            return result.doubleValue
        } else {
            String.numberFormatter.decimalSeparator = ","
            if let result = String.numberFormatter.number(from: self) {
                return result.doubleValue
            }
        }
        return 0
    }
}



使用NumberFormatter的本地化方法:

extension NumberFormatter {
    static let shared = NumberFormatter()
}
extension StringProtocol {
    var doubleValue: Double? {
        return NumberFormatter.shared.number(from: String(self))?.doubleValue
    }
}

操场测试

// User device's default settings for current locale (en_US)
NumberFormatter.shared.locale            // en_US (current)
NumberFormatter.shared.numberStyle       // none
NumberFormatter.shared.decimalSeparator  // "."
"2.7".doubleValue  // 2.7
"2,7".doubleValue  // nil
"$2.70".doubleValue  // nil

NumberFormatter.shared.numberStyle  = .currency
"2.7".doubleValue  // nil
"2,7".doubleValue  // nil
"$2.70".doubleValue  // 2.7


NumberFormatter.shared.locale  = Locale(identifier: "pt_BR") // pt_BR (fixed)
"2.7".doubleValue     // nil
"2,7".doubleValue     // nil
"R$2,70".doubleValue  // 2.7

NumberFormatter.shared.numberStyle = .none
"2.7".doubleValue      // nil
"2,7".doubleValue      // 2.7
"R$2,70".doubleValue   // nil

希望,这对您有所帮助:)

由于NSNumberFormatter在最新版本的Swift中被NumberFormatter取代,我很高兴与您分享一个升级的可能解决方案:

var numberFormatter: NumberFormatter()
importo = Float(numberFormatter.number(from: importoPrevistoTF.text!)!)

Swift 3:包含逗号浮点的字符串的浮点或双精度值

extension String {
    var floatValue: Float {
        let nf = NumberFormatter()
        nf.decimalSeparator = "."
        if let result = nf.number(from: self) {
            return result.floatValue
        } else {
            nf.decimalSeparator = ","
            if let result = nf.number(from: self) {
                return result.floatValue
            }
        }
        return 0
    }

    var doubleValue:Double {
        let nf = NumberFormatter()
        nf.decimalSeparator = "."
        if let result = nf.number(from: self) {
            return result.doubleValue
        } else {
            nf.decimalSeparator = ","
            if let result = nf.number(from: self) {
                return result.doubleValue
            }
        }
        return 0
    }
}
例如:

"5,456".floatValue //5.456
"5.456".floatValue //5.456
"5,456".doubleValue //5.456
"5.456".doubleValue //5.456

"5,456".doubleValue.rounded() //5
"5,6".doubleValue.rounded() //6

我找到了一个解决方案:

let nf = NumberFormatter()
nf.locale = Locale.current
let numberLocalized = nf.number(from: txtAlcool.text!)

在我的例子中,我在xcode上测试,一切正常,但在设备上测试时,它崩溃了。这都是因为在巴西我们使用公制,逗号分隔的十进制“,”。使用此解决方案,它会自动从逗号转换为点。

Swift 4解决方案,无需使用首选语言,我与fr_US和decimalPad之间存在问题

extension String {

     func number(style: NumberFormatter.Style = .decimal) -> NSNumber? {
        return [[Locale.current], Locale.preferredLanguages.map { Locale(identifier: $0) }]
            .flatMap { $0 }
            .map { locale -> NSNumber? in
                let formatter = NumberFormatter()
                formatter.numberStyle = style
                formatter.locale = locale
                return formatter.number(from: self)
        }.filter { $0 != nil }
        .map { $0! }
        .first
    }
}

textfield.text?.number()?.floatValue

您可以使用
NumberFormatter
并过滤不同的十进制分隔符来转换它:

func getDoubleFromLocalNumber(input: String) -> Double {
    var value = 0.0
    let numberFormatter = NumberFormatter()
    let decimalFiltered = input.replacingOccurrences(of: "٫|,", with: ".", options: .regularExpression)
    numberFormatter.locale = Locale(identifier: "EN")
    if let amountValue = numberFormatter.number(from: decimalFiltered) {
        value = amountValue.doubleValue
    }
    return value
}

使用当前版本Swift的代码:

let amount = "8,35"

var counter: Int = 0
var noCommaNumber: String!
for var carattere in (amount) {
    if carattere == "," { carattere = "." }
    if counter != 0 { noCommaNumber = "\(noCommaNumber ?? "\(carattere)")" + "\(carattere)" } else { noCommaNumber = "\(carattere)" } // otherwise first record will always be nil
    counter += 1
}

let importo = Float(noCommaNumber)

显示您的代码。更多的国家使用十进制逗号。大于小数点,请参见:。哦,我真不敢相信美国还不使用公制单位@扎夫,总的来说,我们都是白痴我们在学校半心半意地教公制。加拿大做得对。从70年代初开始,他们就不再教孩子们“帝国”制,而是改用了。@Duncac我们并不孤单,利比里亚和缅甸也不使用公制,就是这样,只有我们三个人。添加了有问题的代码。我认为公制更聪明,我只是不明白为什么不找到一个折衷办法,在每个人身上都使用逗号或点…如果使用Swift,那将是一个副本…非常感谢!我刚用Swift翻译完,就看到你的回答了!问题是
formatter.numberFromString(label)
可能返回
nil
,如果区域设置与字符串格式不匹配,它将返回nil。我承认我以前没有看到过这个问题……但这个解决方案要好得多!这是一个次优的解决方案。看到或不认为本地化有一个奇怪的问题。对于一些区域格式,例如意大利语、点和逗号,但对于其他格式,例如美国,点工作但逗号崩溃;怎么可能?可选-部分:93000000000007
extension String {

     func number(style: NumberFormatter.Style = .decimal) -> NSNumber? {
        return [[Locale.current], Locale.preferredLanguages.map { Locale(identifier: $0) }]
            .flatMap { $0 }
            .map { locale -> NSNumber? in
                let formatter = NumberFormatter()
                formatter.numberStyle = style
                formatter.locale = locale
                return formatter.number(from: self)
        }.filter { $0 != nil }
        .map { $0! }
        .first
    }
}

textfield.text?.number()?.floatValue
func getDoubleFromLocalNumber(input: String) -> Double {
    var value = 0.0
    let numberFormatter = NumberFormatter()
    let decimalFiltered = input.replacingOccurrences(of: "٫|,", with: ".", options: .regularExpression)
    numberFormatter.locale = Locale(identifier: "EN")
    if let amountValue = numberFormatter.number(from: decimalFiltered) {
        value = amountValue.doubleValue
    }
    return value
}
let amount = "8,35"

var counter: Int = 0
var noCommaNumber: String!
for var carattere in (amount) {
    if carattere == "," { carattere = "." }
    if counter != 0 { noCommaNumber = "\(noCommaNumber ?? "\(carattere)")" + "\(carattere)" } else { noCommaNumber = "\(carattere)" } // otherwise first record will always be nil
    counter += 1
}

let importo = Float(noCommaNumber)