You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UITextField中NumberFormatter异常:输入超千后数值重置

问题修复:UITextField千位分隔空格导致数值重置

问题根源

当输入到1000时,格式化后的文本变为1 000,继续输入字符后,TextField的文本变成1 0000,此时直接用Int(text)转换会失败(字符串包含空格,Int无法解析),返回nil,最终导致formatter.string(for: nil)返回nil,TextField内容被清空。

修复方案

修改textFieldFilter方法,先清理输入文本中的非数字字符,再进行格式化,同时修复光标位置问题:

@objc private func textFieldFilter(_ textField: UITextField) {
    guard let originalText = textField.text else { return }
    
    // 1. 移除所有非数字字符,保留纯数字字符串
    let cleanText = originalText.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
    
    // 2. 将纯数字字符串转为数字,若为空则返回空字符串
    guard let number = Double(cleanText), cleanText.count > 0 else {
        textField.text = ""
        return
    }
    
    // 3. 配置格式化器
    let formatter = NumberFormatter()
    formatter.groupingSeparator = " "
    formatter.usesGroupingSeparator = true
    formatter.groupingSize = 3
    formatter.numberStyle = .decimal
    
    // 4. 格式化数字并设置回TextField,同时修复光标位置
    if let formattedText = formatter.string(for: number) {
        // 记录原光标位置
        let cursorOffset = textField.offset(from: textField.beginningOfDocument, to: textField.selectedTextRange!.start)
        textField.text = formattedText
        
        // 计算新光标位置:减去被移除的非数字字符数量
        let removedCharCount = originalText.count - cleanText.count
        let newCursorOffset = max(0, cursorOffset - removedCharCount)
        if let newPosition = textField.position(from: textField.beginningOfDocument, offset: newCursorOffset) {
            textField.selectedTextRange = textField.textRange(from: newPosition, to: newPosition)
        }
    }
}

关键改进点

  • 输入文本清理:先过滤掉所有非数字字符,确保数字转换不会因为空格或符号失败。
  • 光标位置修复:格式化后自动调整光标到正确位置,避免输入体验卡顿。
  • 空值边界处理:输入为空时直接清空TextField,避免异常情况。

内容的提问来源于stack exchange,提问作者S1mpledev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 04:02:24