我希望用户只在UITextField
中输入数值。在iPhone上我们可以显示数字键盘,但在iPad上,用户可以切换到任何键盘。
有没有办法限制用户只输入UITextField
中的数值?
答案 0 :(得分:75)
这是我的2分。 (仅在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
}
这只是一点点严格。没有小数点。
希望有所帮助:)
PS:无论如何,我认为你照顾了代表。
更新:Swift 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
}
答案 1 :(得分:67)
swift 3.0及以上版本的解决方案
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)
}
答案 2 :(得分:13)
在Swift 4.1和Xcode 9.4.1中
将 UITextFieldDelegate 添加到您的班级
class YourViewController: UIViewController, UITextFieldDelegate
然后将此代码写入您的 viewDidLoad()
mobileNoTF.delegate = self
编写此文本字段委托函数
//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
}
答案 3 :(得分:11)
Swift 2.0
仅允许数字和一个"。" 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
}
}
}
答案 4 :(得分:9)
在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
}
}
}
答案 5 :(得分:6)
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
}
即使用户切换键盘或尝试将非数字字符串粘贴到文本字段中,此解决方案仍然有效。
确保设置相应文本字段的delegate
属性。
答案 6 :(得分:5)
仅支持iPhone的解决方案
在您从中获取这些值的任何UITextField中,您可以指定当某人触摸文本字段时您想要显示的键盘类型。
E.G。一个纯数字键盘。
喜欢这个截图:
<强> ipad公司强>
iPad不支持数字键盘,因此您可以选择不支持iPad,验证提交后的字段,也可以按照此处的其他建议在iPad上运行时创建理智的行为。
答案 7 :(得分:3)
//代替这些,您只需将键盘更改为数字类型
yourtextfield.keyboardType = UIKeyboardType.numberPad
答案 8 :(得分:3)
使用数字格式化程序
Swift 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
}
答案 9 :(得分:3)
这是一个简单的解决方案,您需要在控制器中将“编辑已更改”事件连接到此方法
Swift 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()
}
}
}
答案 10 :(得分:3)
设置KeyboardType属性:-数字键盘 TextField委托,请在下面的代码中编写
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)
}
数字不应从0开始,而输入数字+ ve。
答案 11 :(得分:2)
在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
}
答案 12 :(得分:2)
虽然大多数这些解决方案都有效,但请注意,在某些本地化中,小数位用&#34;,&#34;而不是&#34;。&#34;
更简洁的方法是
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
}
答案 13 :(得分:2)
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if let numRange = string.rangeOfCharacterFromSet(NSCharacterSet.letterCharacterSet()) {
return false
} else {
return true
}
}
答案 14 :(得分:2)
要仅允许数字和一个十进制运算符,您可以使用此解决方案:
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)
}
答案 15 :(得分:2)
以下解决方案有两个好处:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
return NumberFormatter().numberFrom(text: (textField.text ?? "") + string) != nil
}
答案 16 :(得分:2)
像这样扩展你的视图控制器:
class MyViewController: UIViewController, UITextFieldDelegate
在viewDidLoad函数中扩展到您的文本字段,如下所示:
myTextField.delegate = self
然后使用以下功能:
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
}
现在确保用户只能输入十进制数字。
斯威夫特4 + 仅接受数字 并接受一个分隔符
答案 17 :(得分:2)
首先,您必须自己继承UITextFieldDelegate类 课
class ViewController: UIViewController, UITextFieldDelegate {
第二次添加IBOutlet
@IBOutlet weak var firstName: UITextField!
第三个必须确保该对象正在使用
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
}
}
答案 18 :(得分:2)
在完成Big Nerd Ranch书时我实际上已经完成了这个,我的解决方案是:
func textField(textField: UITextField,
shouldChangeCharactersInRange range: NSRange,
replacementString string: String) -> Bool {
let newCharacters = NSCharacterSet(charactersInString: string)
return NSCharacterSet.decimalDigitCharacterSet().isSupersetOfSet(newCharacters)
}
这只允许数字0-9,以允许“。”同样更复杂,因为你只能允许一个“。”
答案 19 :(得分:1)
允许一些特征
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
答案 20 :(得分:1)
我编辑了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
}
}
}
答案 21 :(得分:1)
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
}
上面代码中的在swift 3中工作
NSCharacterSet。的 decimalDigits 强>
你也只用字母
NSCharacterSet。的字母强>
和大写,小写字母,字母数字,空格
使用相同的代码
或See the Link
答案 22 :(得分:1)
我认为您可以通过实现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
}
}
}
答案 23 :(得分:1)
这是一个更清洁的解决方案:
guard CharacterSet(charactersIn: "123456789").isSuperset(of: CharacterSet(charactersIn: string)) else {
return false
}
return true
对于小数,只需添加.
,例如123456789.
答案 24 :(得分:1)
以下是我在Swift 3.0中使用的代码,该代码改编自Mr H的代码。差异是因为:
a)Swift 3.0中的委托函数声明已更改。 New declaration here
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
}
答案 25 :(得分:1)
好像没有足够的答案,这就是我的。我认为允许小数分隔符的每个例子在本地化,退格或复制/粘贴方面都存在缺陷。
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
}
答案 26 :(得分:0)
同时解决小数和整数的方法:
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
}
答案 27 :(得分:0)
Double
代表的UITextFieldDelegate
数字的死简单解决方案(请注意,这不是最好的用户友好型解决方案):
func textField(_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
guard let currentString = textField.text as NSString? else {
return false
}
let newString = currentString.replacingCharacters(in: range, with: string)
return Double(newString) != nil
}
答案 28 :(得分:0)
Swift 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
}
答案 29 :(得分:0)
如果要允许小数分隔符和/或负数,可以使用此代码。 但是这段代码允许例子:“34。” (更改文本时的结尾处的小数点分隔符)。所以你必须添加一些代码示例:textFieldShouldReturn或textFieldShouldEndEditing委托函数。
用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
}
如果您不想允许小数或负数,则必须用下一行替换tow变量
let allowDecimal = ""
let allowSign = ""
答案 30 :(得分:0)
您可以使用shouldChangeCharactersInRange和String扩展方法来检查输入字符串是否为数字。
extension String {
var isNumber : Bool {
get{
return !self.isEmpty && self.stringWithoutWhitespaces.rangeOfCharacter(from: CharacterSet.decimalDigits.inverted) == nil
}
}
var stringWithoutWhitespaces: String {
return self.replacingOccurrences(of: " ", with: "")
}
}
//Mark: shouldChangeCharactersInRange
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
// return true if the string only contains numeric characters
let isValid = string.stringWithoutWhitespaces.isNumber
return valid
}
答案 31 :(得分:0)
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
}
答案 32 :(得分:0)
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
}
}
如果有此功能,请将此功能放入“提交”或“保存”方法。
答案 33 :(得分:0)
这是一个更易阅读的版本,可以做&#34; 0-9&#34;加上#34;。&#34;:
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
}
}
}
答案 34 :(得分:-1)
首先添加delegate
keyBoradType
和textField
textField.delegate=self;
textField.keyboardType = UIKeyboardTypeNumberPad;
比必须使用textField.delegate
方法 -
- (BOOL) textField: (UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString: (NSString *)string
{
if (!string.length)
{
return YES;
}
if ([string intValue])
{
return YES;
}
return NO;
}
答案 35 :(得分:-1)
//只接受十进制数作为输入,[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
}
答案 36 :(得分:-1)
更新了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
}
}
}