[英]How to restrict UITextField to take only numbers in Swift?
I want the user to only enter numeric values in a UITextField
.我希望用户只在
UITextField
输入数值。 On iPhone we can show the numeric keyboard, but on iPad the user can switch to any keyboard.在 iPhone 上,我们可以显示数字键盘,但在 iPad 上,用户可以切换到任何键盘。
Is there any way to restrict user to enter only numeric values in a UITextField
?有没有办法限制用户只能在
UITextField
输入数值?
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let allowedCharacters = CharacterSet.decimalDigits
let characterSet = CharacterSet(charactersIn: string)
return allowedCharacters.isSuperset(of: characterSet)
}
Here is my 2 Cents.这是我的 2 美分。 (Tested on Swift 2 Only)
(仅在 Swift 2 上测试)
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
let aSet = NSCharacterSet(charactersInString:"0123456789").invertedSet
let compSepByCharInSet = string.componentsSeparatedByCharactersInSet(aSet)
let numberFiltered = compSepByCharInSet.joinWithSeparator("")
return string == numberFiltered
}
This is just a little bit more strict.这只是稍微严格一点。 No decimal point either.
也没有小数点。
Hope it helps :)希望能帮助到你 :)
PS: I assumed you looked after the delegate anyway. PS:我假设你无论如何都会照顾代表。
Update: Swift 3.0 :更新:斯威夫特 3.0 :
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let aSet = NSCharacterSet(charactersIn:"0123456789").inverted
let compSepByCharInSet = string.components(separatedBy: aSet)
let numberFiltered = compSepByCharInSet.joined(separator: "")
return string == numberFiltered
}
In swift 4.1 and Xcode 9.4.1在 swift 4.1 和 Xcode 9.4.1 中
Add UITextFieldDelegate to your class将UITextFieldDelegate添加到您的班级
class YourViewController: UIViewController, UITextFieldDelegate
Then write this code in your viewDidLoad()然后在您的viewDidLoad() 中编写此代码
mobileNoTF.delegate = self
Write this textfield delegate function编写此文本字段委托函数
//MARK - UITextField Delegates
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
//For mobile numer validation
if textField == mobileNoTF {
let allowedCharacters = CharacterSet(charactersIn:"+0123456789 ")//Here change this characters based on your requirement
let characterSet = CharacterSet(charactersIn: string)
return allowedCharacters.isSuperset(of: characterSet)
}
return true
}
Swift 2.0斯威夫特 2.0
For only allowing numbers and one "."因为只允许数字和一个“.” decimal in uitextfield.
uitextfield 中的十进制数。
func textField(textField: UITextField,shouldChangeCharactersInRange range: NSRange,replacementString string: String) -> Bool
{
let newCharacters = NSCharacterSet(charactersInString: string)
let boolIsNumber = NSCharacterSet.decimalDigitCharacterSet().isSupersetOfSet(newCharacters)
if boolIsNumber == true {
return true
} else {
if string == "." {
let countdots = textField.text!.componentsSeparatedByString(".").count - 1
if countdots == 0 {
return true
} else {
if countdots > 0 && string == "." {
return false
} else {
return true
}
}
} else {
return false
}
}
}
IPhone only solution仅限 iPhone 的解决方案
In whatever UITextField you're getting these values from, you can specify the kind of keyboard you want to appear when somebody touches inside the text field.无论您从哪个 UITextField 获取这些值,您都可以指定当有人触摸文本字段时要显示的键盘类型。
EG a numeric-only keyboard. EG 仅数字键盘。
Like this screenshot:像这个截图:
Ipad平板电脑
The iPad does not support the numeric keyboard, so your options are to either not support the iPad, validate the field post submit, or follow one of the other suggestions here to create same behaviors while running on an iPad. iPad 不支持数字键盘,因此您可以选择不支持 iPad、验证现场提交提交,或按照此处的其他建议之一在 iPad 上运行时创建相同的行为。
Accept decimal values in text fields with single (.)dot in Swift 3在 Swift 3 中接受带有单个 (.) 点的文本字段中的十进制值
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let inverseSet = NSCharacterSet(charactersIn:"0123456789").inverted
let components = string.components(separatedBy: inverseSet)
let filtered = components.joined(separator: "")
if filtered == string {
return true
} else {
if string == "." {
let countdots = textField.text!.components(separatedBy:".").count - 1
if countdots == 0 {
return true
}else{
if countdots > 0 && string == "." {
return false
} else {
return true
}
}
}else{
return false
}
}
}
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
// return true if the replacementString only contains numeric characters
let digits = NSCharacterSet.decimalDigitCharacterSet()
for c in string {
if !digits.characterIsMember(c) {
return false
}
}
return true
}
This solution will work even if the user switches keyboards or tries to paste a non-numeric string into the text field.即使用户切换键盘或尝试将非数字字符串粘贴到文本字段中,此解决方案也将起作用。
Make sure to set the delegate
property of the appropriate text field.确保设置相应文本字段的
delegate
属性。
Use number formatter使用数字格式化程序
Swift 4.x斯威夫特 4.x
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let s = NSString(string: textField.text ?? "").replacingCharacters(in: range, with: string)
guard !s.isEmpty else { return true }
let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = .none
return numberFormatter.number(from: s)?.intValue != nil
}
Extend your view controller like this:像这样扩展你的视图控制器:
class MyViewController: UIViewController, UITextFieldDelegate
In the viewDidLoad function extend to your text field like this:在 viewDidLoad 函数中,像这样扩展到您的文本字段:
myTextField.delegate = self
And then use the following function:然后使用以下函数:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let isNumber = CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: string))
let withDecimal = (
string == NumberFormatter().decimalSeparator &&
textField.text?.contains(string) == false
)
return isNumber || withDecimal
}
This will now make sure the user can enter only decimal digits.这将确保用户只能输入十进制数字。
Swift 4 + Accepts Number only and accepts one separator Swift 4 + 仅接受数字并接受一个分隔符
Here is a simple solution, you need to connect the event "Editing changed" to this method in your controller这是一个简单的解决方案,您需要将事件“编辑更改”连接到控制器中的此方法
Swift 4斯威夫特 4
@IBAction func valueChanged(_ sender: UITextField) {
if let last = sender.text?.last {
let zero: Character = "0"
let num: Int = Int(UnicodeScalar(String(last))!.value - UnicodeScalar(String(zero))!.value)
if (num < 0 || num > 9) {
//remove the last character as it is invalid
sender.text?.removeLast()
}
}
}
1st you have to inherit the UITextFieldDelegate class with you own class
1st 你必须用你自己的类继承 UITextFieldDelegate 类
class ViewController: UIViewController, UITextFieldDelegate {
2nd add an IBOutlet
2 添加一个 IBOutlet
@IBOutlet weak var firstName: UITextField!
3rd you have to assure this object is using
第三,你必须确保这个对象正在使用
override func viewDidLoad() {
super.viewDidLoad()
firstName.delegate = self
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if textField == firstName {
let allowedCharacters = "1234567890"
let allowedCharacterSet = CharacterSet(charactersIn: allowedCharacters)
let typedCharacterSet = CharacterSet(charactersIn: string)
let alphabet = allowedCharacterSet.isSuperset(of: typedCharacterSet)
return alphabet
}
}
Tested in swift 3.0在 swift 3.0 中测试
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
{
let numberOnly = NSCharacterSet.init(charactersIn: "0123456789")
let stringFromTextField = NSCharacterSet.init(charactersIn: string)
let strValid = numberOnly.isSuperset(of: stringFromTextField as CharacterSet)
return strValid
}
While most of these solutions will work, be aware that in some localisations a decimals are separated with a "," and not a "."虽然这些解决方案中的大多数都有效,但请注意,在某些本地化中,小数位用“,”而不是“”分隔。
The cleaner way to do this would be更干净的方法是
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
let decimalCharacter = NSNumberFormatter().decimalSeparator
let characterSet = NSMutableCharacterSet.decimalDigitCharacterSet()
characterSet.addCharactersInString(decimalCharacter)
return replacementString.rangeOfCharacterFromSet(characterSet.invertedSet) == nil
}
Here's an cleaner solution:这是一个更清洁的解决方案:
guard CharacterSet(charactersIn: "123456789").isSuperset(of: CharacterSet(charactersIn: string)) else {
return false
}
return true
For decimals just add .
对于小数,只需添加
.
, example 123456789.
,例如
123456789.
Set KeyboardType Property :- Number Pad TextField Delegate please write below code设置键盘类型属性:-数字键盘文本字段委托请写下面的代码
func textField(_ textField: UITextField, shouldChangeCharactersIn
range: NSRange, replacementString string: String) -> Bool {
if textField.text?.count == 0 && string == "0" {
return false
}
return string == string.filter("0123456789".contains)
}
Number should not start from 0 and entered number +ve.数字不应从 0 开始并输入数字 +ve。
I had actually done this when working through the Big Nerd Ranch book, my solution is:我在阅读 Big Nerd Ranch 的书时实际上已经这样做了,我的解决方案是:
func textField(textField: UITextField,
shouldChangeCharactersInRange range: NSRange,
replacementString string: String) -> Bool {
let newCharacters = NSCharacterSet(charactersInString: string)
return NSCharacterSet.decimalDigitCharacterSet().isSupersetOfSet(newCharacters)
}
this only allows the numbers 0-9, to allow the "."这仅允许数字 0-9,以允许“。” as well is more complicated as you can only allow one "."
也更复杂,因为您只能允许一个“。”
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if let numRange = string.rangeOfCharacterFromSet(NSCharacterSet.letterCharacterSet()) {
return false
} else {
return true
}
}
To allow only numbers and just one decimal operator, you can use this solution:要仅允许数字和一个小数运算符,您可以使用以下解决方案:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
let isNumber = NSCharacterSet.decimalDigitCharacterSet().isSupersetOfSet(NSCharacterSet(charactersInString: string))
return isNumber || (string == NSNumberFormatter().decimalSeparator && textField.text?.containsString(string) == false)
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
{
let textString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
if textField == self.phoneTextField && string.characters.count > 0{
let numberOnly = NSCharacterSet.decimalDigits
let strValid = numberOnly.contains(UnicodeScalar.init(string)!)
return strValid && textString.characters.count <= 10
}
return true
}
in above code is working in swift 3上面的代码在 swift 3 中工作
NSCharacterSet. NSCharacterSet。 decimalDigits
十进制数字
You are also use letters only您也只能使用字母
NSCharacterSet. NSCharacterSet。 Letters
信件
and uppercase,Lowercaseand,alphanumerics,whitespaces is used same code or See the Link和大写、小写和字母数字、空格使用相同的代码或查看链接
The following solution has two benefits:以下解决方案有两个好处:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
return NumberFormatter().numberFrom(text: (textField.text ?? "") + string) != nil
}
// 而不是这些,您可以简单地将键盘更改为数字类型
yourtextfield.keyboardType = UIKeyboardType.numberPad
I think you can force change the keyboard type by implementing UITextInputTraits protocol, optional var keyboardType我认为您可以通过实现 UITextInputTraits 协议强制更改键盘类型,可选 var keyboardType
//class ViewController: UIViewController, UITextInputTraits {
@IBOutlet weak var textFieldKeyboardType: UITextField!{
didSet{
textFieldKeyboardType.keyboardType = UIKeyboardType.NumberPad
}
}
var keyboardType: UIKeyboardType {
get{
return textFieldKeyboardType.keyboardType
}
set{
if newValue != UIKeyboardType.NumberPad{
self.keyboardType = UIKeyboardType.NumberPad
}
}
}
This is a more readable version that will do "0-9" plus ".":这是一个更具可读性的版本,它将执行“0-9”加“.”:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
let existingTextHasDecimal = textField.text?.rangeOfString(".")
let replacementTextHasDecimal = string.rangeOfString(".")
let replacementTextAllCharacters = NSCharacterSet(charactersInString: string)
let replacementTextOnlyDigits = NSCharacterSet.decimalDigitCharacterSet().isSupersetOfSet(replacementTextAllCharacters)
if replacementTextHasDecimal != nil && existingTextHasDecimal != nil {
return false
}else{
if replacementTextOnlyDigits == true {
return true
}else if replacementTextHasDecimal != nil{
return true
}else{
return false
}
}
}
As if there aren't enough answers, here's mine.好像没有足够的答案,这是我的。 I think every example allowed for decimal separators is flawed in either localization, backspaces, or copy/paste.
我认为允许使用小数点分隔符的每个示例在本地化、退格或复制/粘贴方面都有缺陷。
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if string.isEmpty {return true} //allow for backspace
let decimalSeparator = NSNumberFormatter().decimalSeparator ?? "."
let validChars = NSMutableCharacterSet(charactersInString: decimalSeparator)
validChars.formUnionWithCharacterSet(NSCharacterSet.decimalDigitCharacterSet())
if validChars.isSupersetOfSet(NSCharacterSet(charactersInString: string)){
switch string.componentsSeparatedByString(decimalSeparator).count-1 {
case 0: //no decimals
return true
case 1: //if adding decimal, only allow if no existing decimal
if let existingText = textField.text{
return existingText.componentsSeparatedByString(decimalSeparator).count <= 1
}
else {return true}
default: //invalid decimals
return false
}
}
return false
}
The following is the code I used in Swift 3.0 adapted from Mr H's code.以下是我在 Swift 3.0 中使用的代码,改编自 Mr H 的代码。 Differences are because:
差异是因为:
a) Delegate function declaration has changed in Swift 3.0. a) Swift 3.0 中的委托函数声明已更改。 New declaration here
新声明在这里
b) NSCharacterSet declaration has changed. b) NSCharacterSet 声明已更改。
func textField(_ shouldChangeCharactersIntextField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
{
let inverseSet = NSCharacterSet(charactersIn:"0123456789").inverted
let components = string.components(separatedBy: inverseSet)
let filtered = components.joined(separator: "")
return string == filtered
}
I have edited Raj Joshi's version to allow one dot or one comma:我编辑了 Raj Joshi 的版本以允许一个点或一个逗号:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let inverseSet = CharacterSet(charactersIn:"0123456789").inverted
let components = string.components(separatedBy: inverseSet)
let filtered = components.joined(separator: "")
if filtered == string {
return true
} else {
if string == "." || string == "," {
let countDots = textField.text!.components(separatedBy:".").count - 1
let countCommas = textField.text!.components(separatedBy:",").count - 1
if countDots == 0 && countCommas == 0 {
return true
} else {
return false
}
} else {
return false
}
}
}
You can use this code if you want to allow decimal separator and/or negative numbers.如果您想允许小数分隔符和/或负数,您可以使用此代码。 But this code allows example: "34."
但是此代码允许示例:“34”。 (decimal separator at the end) while changing text.
(末尾的小数分隔符)同时更改文本。 So you have to add some code example: textFieldShouldReturn or textFieldShouldEndEditing delegate functions.
所以你必须添加一些代码示例:textFieldShouldReturn 或 textFieldShouldEndEditing 委托函数。
The code written in Swift 4 but I assueme this is compatible with Swift 3.用 Swift 4 编写的代码,但我认为这与 Swift 3 兼容。
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard let text = textField.text else {
return true
}
let replaced = (text as NSString).replacingCharacters(in: range, with: string)
let decimalSeparator = NSLocale.current.decimalSeparator ?? ""
// When user wants to delete las character
if replaced == "" || replaced == "-" || replaced == "-0" {
textField.text = "0"
return false
}
// When text contains 0 before replace except "0."
if replaced != "0" + decimalSeparator && replaced.hasPrefix("0") && text.underestimatedCount == 1 {
textField.text = replaced.substring(from: replaced.index(after: replaced.startIndex))
return false
}
// When user wants to delete minus sign
if text.hasPrefix("-") && text.substring(from: text.index(after: text.startIndex)) == replaced {
return false
}
// When user wants to delete before decimal separator
if replaced.hasPrefix(decimalSeparator) || replaced.hasPrefix("-" + decimalSeparator) {
return false
}
// When user wants to add zero the beginning of number... but allowing "0." or "-0." numbers
let testReplaced = replaced.hasPrefix("-") ? replaced.substring(from: replaced.index(after: replaced.startIndex)) : replaced
if testReplaced.count >= 2 && testReplaced.hasPrefix("0") && !testReplaced.hasPrefix("0" + decimalSeparator) {
return false
}
// Every other cases
let allowDecimal = self.allowFloat ? (decimalSeparator == "." ? "\\.?" : decimalSeparator + "?") : ""
let allowSign = self.allowSigned ? "-?" : ""
let pattern = "\(allowSign)[0-9]+\(allowDecimal)([0-9]+)?"
do {
let regexRange = (replaced as NSString).range(of: replaced)
let regex = try NSRegularExpression(pattern: pattern, options: [])
let matches = regex.matches(in: replaced, options: [], range: regexRange)
return matches.count == 1 && matches.first!.range == regexRange
}
catch {}
return false
}
If you don't want to allow decimal or negative numbers you have to replace tow variable with next line如果你不想允许十进制或负数,你必须用下一行替换拖曳变量
let allowDecimal = ""
let allowSign = ""
For allow some charactors允许一些字符
func CheckAddress(string:String) -> Bool {
let numberOnly = NSCharacterSet.init(charactersIn: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-@,&#/")
let stringFromTextField = NSCharacterSet.init(charactersIn: string)
return numberOnly.isSuperset(of: stringFromTextField as CharacterSet)
}
print("\(CheckAddress(string: "123"))") //True
print("\(CheckAddress(string: "asdf-"))") //True
print("\(CheckAddress(string: "asd123$"))") //false
Swift 2.0
func textField(textField: UITextField,
shouldChangeCharactersInRange range: NSRange,
replacementString string: String) -> Bool {
let inverseSet = NSCharacterSet(charactersInString:"0123456789").invertedSet
let components = string.componentsSeparatedByCharactersInSet(inverseSet)
let filtered = components.joinWithSeparator("")
return string == filtered
}
func isValidNumber(str:String) -> Bool{
if str.isEmpty {
return false
}
let newChar = NSCharacterSet(charactersInString: str)
let boolValid = NSCharacterSet.decimalDigitCharacterSet().isSupersetOfSet(newChar)
if boolValid{
return true
}else{
let lst = str.componentsSeparatedByString(".")
let newStr = lst.joinWithSeparator("")
let currentChar = NSCharacterSet(charactersInString: newStr)
if lst.count == 2 && !lst.contains("") && NSCharacterSet.decimalDigitCharacterSet().isSupersetOfSet(currentChar){
return true
}
return false
}
}
Put this function in your "Submit" or "Save" method if there is one.如果有的话,把这个函数放在你的“提交”或“保存”方法中。
I want the user to only enter numeric values in a UITextField
.我希望用户仅在
UITextField
输入数字值。 On iPhone we can show the numeric keyboard, but on iPad the user can switch to any keyboard.在iPhone上,我们可以显示数字键盘,但是在iPad上,用户可以切换到任何键盘。
Is there any way to restrict user to enter only numeric values in a UITextField
?有什么方法可以限制用户在
UITextField
仅输入数字值?
I want the user to only enter numeric values in a UITextField
.我希望用户仅在
UITextField
输入数字值。 On iPhone we can show the numeric keyboard, but on iPad the user can switch to any keyboard.在iPhone上,我们可以显示数字键盘,但是在iPad上,用户可以切换到任何键盘。
Is there any way to restrict user to enter only numeric values in a UITextField
?有什么方法可以限制用户在
UITextField
仅输入数字值?
Swift 3 迅捷3
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if textField==yourTextFieldOutlet {
if(CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: yourTextFieldOutlet.text!))){
//if numbers only, then your code here
}
else{
showAlert(title: "Error",message: "Enter Number only",type: "failure")
}
}
return true
}
An approach that solves both decimal and Int:一种解决decimal和Int的方法:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let currentText = textField.text
let futureString = currentText.substring(toIndex: range.location) + string + currentText.substring(fromIndex: range.location + range.length)
if futureString.count == 0 {
return true
}
if isDecimal {
if let numberAsDouble = Double(futureString), numberAsDouble.asPrice.count >= futureString.count {
return true
}
} else if let numberAsInt = Int(futureString), "\(numberAsInt)".count == futureString.count {
return true
}
return false
}
First add delegate
and keyBoradType
of textField
首先添加
textField
delegate
和keyBoradType
textField.delegate=self; textField.keyboardType = UIKeyboardTypeNumberPad;
Than have to use the textField.delegate
method like so -比必须像这样使用
textField.delegate
方法 -
- (BOOL) textField: (UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString: (NSString *)string
{
if (!string.length)
{
return YES;
}
if ([string intValue])
{
return YES;
}
return NO;
}
更新了 Cian 对 Swift 3 的回应:
func textField(textField: UITextField,shouldChangeCharactersInRange range: NSRange,replacementString string: String) -> Bool { let newCharacters = NSCharacterSet(charactersIn: string) let boolIsNumber = NSCharacterSet.decimalDigits.isSuperset(of:newCharacters as CharacterSet) if boolIsNumber == true { return true } else { if string == "." { let countdots = textField.text!.components(separatedBy:".").count - 1 if countdots == 0 { return true } else { if countdots > 0 && string == "." { return false } else { return true } } } else { return false } } }
//Only accept decimal numbers as input, [ SWIFT 3.0 ] //只接受十进制数作为输入,[SWIFT 3.0]
func textField(_ shouldChangeCharactersIntextField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
{
let inverseSet = NSCharacterSet(charactersIn:"0123456789").inverted
let components = string.components(separatedBy: inverseSet)
let filtered = components.joined(separator: "")
return string == filtered
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.