iOS Swift4.0+Xcode9输入框实时添加千分位逗号报错排查
解决UITextField实时添加千位分隔符的问题
首先,你遇到的Cannot call value of non-function type 'UITextField'错误,是因为绑定编辑变化事件的代码写法完全错了——UITextField不是方法,不能直接这么调用。正确的做法是用addTarget(_:action:for:)方法来关联编辑变化的响应逻辑。
第一步:修正事件监听代码
把你那行报错的代码替换成下面的正确写法,放在viewDidLoad方法里:
self.mainTextField.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: .editingChanged)
第二步:优化数字格式化逻辑
你的现有格式化方法只处理整数,而且直接粗暴替换小数点会丢失小数部分(如果有需求支持金额类小数的话)。这里给你两个版本的实现,按需选择:
支持整数+小数的通用版本
@objc func textFieldDidChange(textField: UITextField) { guard textField == self.mainTextField, let originalText = textField.text else { return } // 移除所有非数字字符,只保留数字和单个小数点 let cleanedText = originalText.components(separatedBy: CharacterSet.decimalDigits.inverted).joined() let numberFormatter = NumberFormatter() numberFormatter.numberStyle = .decimal numberFormatter.locale = Locale.current // 自动适配当前地区的分隔符规则(比如欧美是逗号,部分地区是点) // 区分整数和小数场景处理 if cleanedText.contains(".") { guard let doubleValue = Double(cleanedText) else { return } textField.text = numberFormatter.string(from: NSNumber(value: doubleValue)) } else { guard let intValue = Int(cleanedText) else { return } textField.text = numberFormatter.string(from: NSNumber(value: intValue)) } }
仅支持整数的简化版本
如果你的需求只需要处理整数,也可以简化成下面的写法,逻辑和你原来的思路一致但更严谨:
@objc func textFieldDidChange(textField: UITextField) { guard textField == self.mainTextField, let originalText = textField.text else { return } // 移除所有已有的分隔符和非数字字符 let cleanedText = originalText.replacingOccurrences(of: ",", with: "").replacingOccurrences(of: ".", with: "") let numberFormatter = NumberFormatter() numberFormatter.numberStyle = .decimal if let intValue = Int(cleanedText) { textField.text = numberFormatter.string(from: NSNumber(value: intValue)) } }
额外优化建议
如果想避免用户输入无效字符(比如字母、多个小数点),可以在UITextFieldDelegate代理方法里做前置过滤:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { // 允许数字、单个小数点和退格键 let allowedChars = CharacterSet.decimalDigits.union(CharacterSet(charactersIn: ".")) let inputChars = CharacterSet(charactersIn: string) // 限制只能输入一个小数点 if string == "." && textField.text?.contains(".") == true { return false } return allowedChars.isSuperset(of: inputChars) }
这样修改后,既能解决你之前的代码报错,也能流畅实现实时添加千位分隔符的需求啦。
内容的提问来源于stack exchange,提问作者mdehghani
相关产品推荐
相关产品推荐

