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

UITextField实时数字验证与格式化:整数及Double类型规则处理问询

刚好之前做项目的时候遇到过一模一样的UITextField数字格式化需求,结合你提到的规则,我整理了一套实用的实现方案,分享给你:

UITextField 数字实时格式化完整实现

一、整数类型处理逻辑

整数的处理相对直接,核心规则如下:

  • 允许输入正负整数,自动过滤所有非数字、非开头负号的无效字符;
  • 支持单独输入负号(用户还未输入数字的过渡状态);
  • 自动识别有效整数格式,比如输入-00123会被转为有效整数-123。

二、Double类型处理逻辑

核心原则是尽可能保留用户输入的原始格式,仅处理三个例外场景:

  1. 当输入以.开头时,自动补前导零为0.;输入以-.开头时,转为-0.;
  2. 当用户删除小数点后,自动移除多余的前导零(比如0.12删除小数点后变成012,需转为12;-0.12删除小数点后变成-012,需转为-12);
  3. 额外限制:仅允许输入一个小数点,负号只能出现在字符串开头。

三、代码实现(Swift)

我用UITextField子类+Delegate的方式实现,方便在项目中复用:

// 定义数字类型枚举,区分整数和浮点数
enum TextFieldNumberType {
    case integer  // 整数类型
    case double   // 浮点数类型
}

class NumberFormatTextField: UITextField {
    // 指定当前TextField的数字类型
    var numberType: TextFieldNumberType = .double
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupTextField()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupTextField()
    }
    
    private func setupTextField() {
        keyboardType = .numbersAndPunctuation
        delegate = self
    }
}

// 实现UITextFieldDelegate,处理实时格式化逻辑
extension NumberFormatTextField: UITextFieldDelegate {
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        guard let currentText = textField.text else { return true }
        let updatedText = (currentText as NSString).replacingCharacters(in: range, with: string)
        
        switch numberType {
        case .integer:
            return handleIntegerInput(updatedText: updatedText)
        case .double:
            return handleDoubleInput(updatedText: updatedText, currentText: currentText, range: range, replacementString: string)
        }
    }
    
    // 整数输入处理
    private func handleIntegerInput(updatedText: String) -> Bool {
        // 允许空输入(用户删除所有内容)
        if updatedText.isEmpty { return true }
        // 允许单独输入负号
        if updatedText == "-" { return true }
        // 验证是否为有效整数
        return Int(updatedText) != nil
    }
    
    // 浮点数输入处理
    private func handleDoubleInput(updatedText: String, currentText: String, range: NSRange, replacementString: String) -> Bool {
        // 允许空输入
        if updatedText.isEmpty { return true }
        
        // 场景1:处理开头为.或-.的情况
        if updatedText == "." {
            self.text = "0."
            return false
        }
        if updatedText == "-." {
            self.text = "-0."
            return false
        }
        
        // 限制只能有一个小数点
        let dotCount = updatedText.filter { $0 == "." }.count
        if dotCount > 1 { return false }
        
        // 场景2:删除小数点后移除多余前导零
        let deletedContent = (currentText as NSString).substring(with: range)
        let isDeletingDot = replacementString.isEmpty && deletedContent == "."
        if isDeletingDot {
            var processedText = updatedText
            // 处理正数:012 → 12;单独的0保留
            if processedText.hasPrefix("0") && processedText.count > 1 && processedText != "0" {
                processedText = String(processedText.dropFirst())
            }
            // 处理负数:-012 → -12;单独的-0保留
            if processedText.hasPrefix("-0") && processedText.count > 2 && processedText != "-0" {
                processedText = "-" + String(processedText.dropFirst(2))
            }
            self.text = processedText
            return false
        }
        
        // 验证输入字符仅为数字、负号(仅开头)、小数点
        let allowedChars = CharacterSet(charactersIn: "0123456789.-")
        let inputChars = CharacterSet(charactersIn: updatedText)
        if !allowedChars.isSuperset(of: inputChars) { return false }
        
        // 确保负号只能在开头
        if updatedText.contains("-") && updatedText.first != "-" { return false }
        
        return true
    }
}

四、使用说明

  1. 在Storyboard或代码中创建NumberFormatTextField实例;
  2. 设置numberType为.integer或.double,即可自动应用对应格式化逻辑;
  3. 如果需要适配区域设置(比如用逗号作为小数点),只需要把代码中的.替换为对应的小数点字符即可。

额外注意事项

  • 若需限制数字范围(比如最大最小值),可在handleIntegerInput或handleDoubleInput中添加额外判断;
  • 测试边界场景:比如输入-0.00、删除小数点后的-000,代码会自动转为-0,若需转为0可调整逻辑;
  • 若用户输入多个前导零(比如000123),整数类型会自动转为123,如果需要实时显示时就去掉前导零,可在整数处理逻辑中添加字符串处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:22:45