检查到UITextField的input只是数字

如何validationinput到UITextField的string? 我想检查string是数字,包括小数点。

我在我的Mac应用程序中使用此代码,相同或类似应与iPhone工作。 它基于RegexKitLite正则expression式,当文本无效时将文本变为红色。

 static bool TextIsValidValue( NSString* newText, double &value ) { bool result = false; if ( [newText isMatchedByRegex:@"^(?:|0|[1-9]\\d*)(?:\\.\\d*)?$"] ) { result = true; value = [newText doubleValue]; } return result; } - (IBAction) doTextChanged:(id)sender; { double value; if ( TextIsValidValue( [i_pause stringValue], value ) ) { [i_pause setTextColor:[NSColor blackColor]]; // do something with the value } else { [i_pause setTextColor:[NSColor redColor]]; } } 

你可以这样做几行:

 BOOL valid; NSCharacterSet *alphaNums = [NSCharacterSet decimalDigitCharacterSet]; NSCharacterSet *inStringSet = [NSCharacterSet characterSetWithCharactersInString:myInputField.text]; valid = [alphaNums isSupersetOfSet:inStringSet]; if (!valid) // Not numeric 

– 这是validationinput只是数字字符。 查看其他选项的NSCharacterSet的文档。 您可以使用characterSetWithCharactersInString指定任何一组有效的input字符。

有几种方法可以做到这一点:

  1. 使用NSNumberFormatter的numberFromString:方法。 这将返回一个NSNumber,如果它可以正确parsingstring,或者如果它不能。
  2. 使用NSScanner
  3. 去掉任何非数字字符,看看string是否仍然匹配
  4. 使用正则expression式

国际海事组织,使用类似于-[NSString doubleValue]不会是最好的select,因为@"0.0"@"abc"将有一个doubleValue为0. *值方法都返回0,如果他们无法转换string正确,因此很难区分@"0"的合法string和无效string。 像C的strtol函数会有同样的问题。

我认为使用NSNumberFormatter将是最好的select,因为它需要考虑locale(即在欧洲的数字@"1,23" ,而在美国是@"1.23" )。

如果你想要一个用户只允许input数字,你可以让你的ViewController实现UITextFieldDelegate的一部分,并定义这个方法:

 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { NSString *resultingString = [textField.text stringByReplacingCharactersInRange: range withString: string]; // The user deleting all input is perfectly acceptable. if ([resultingString length] == 0) { return true; } NSInteger holder; NSScanner *scan = [NSScanner scannerWithString: resultingString]; return [scan scanInteger: &holder] && [scan isAtEnd]; } 

有可能是更有效的方法,但我觉得这是一个非常方便的方法。 而且该方法应该很容易适用于validation双打或其他:只要使用scanDouble:或类似的。

 #pragma mark - UItextfield Delegate - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { if ([string isEqualToString:@"("]||[string isEqualToString:@")"]) { return TRUE; } NSLog(@"Range ==%d ,%d",range.length,range.location); //NSRange *CURRANGE = [NSString rangeOfString:string]; if (range.location == 0 && range.length == 0) { if ([string isEqualToString:@"+"]) { return TRUE; } } return [self isNumeric:string]; } -(BOOL)isNumeric:(NSString*)inputString{ BOOL isValid = NO; NSCharacterSet *alphaNumbersSet = [NSCharacterSet decimalDigitCharacterSet]; NSCharacterSet *stringSet = [NSCharacterSet characterSetWithCharactersInString:inputString]; isValid = [alphaNumbersSet isSupersetOfSet:stringSet]; return isValid; } 

下面是一些将Peter Lewis上面的答案( 检查UITextField的input只是数字 )与NSPredicates结合在一起的单行

  #define REGEX_FOR_NUMBERS @"^([+-]?)(?:|0|[1-9]\\d*)(?:\\.\\d*)?$" #define REGEX_FOR_INTEGERS @"^([+-]?)(?:|0|[1-9]\\d*)?$" #define IS_A_NUMBER(string) [[NSPredicate predicateWithFormat:@"SELF MATCHES %@", REGEX_FOR_NUMBERS] evaluateWithObject:string] #define IS_AN_INTEGER(string) [[NSPredicate predicateWithFormat:@"SELF MATCHES %@", REGEX_FOR_INTEGERS] evaluateWithObject:string] 

对于整数testing,它将是:

 - (BOOL) isIntegerNumber: (NSString*)input { return [input integerValue] != 0 || [input isEqualToString:@"0"]; } 

你可以使用你的string的doubleValue

 NSString *string=@"1.22"; double a=[string doubleValue]; 

我认为这将返回一个0.0如果string是无效的(它可能会抛出一个exception,在这种情况下,你可以抓住它,文档说0.0 tho)。 更多信息在这里

嗨有完全相同的问题,我没有看到我用过的回答,所以在这里。

我通过IB创build并连接了我的文本字段。 当我通过Control + Drag将其连接到我的代码时,我select了Action,然后select了Editing Changed事件。 这会触发每个字符条目的方法。 你可以使用不同的事件来适应。

之后,我用这个简单的代码来replace文本。 请注意,我创build了自己的字符集以包含小数点/句点字符和数字。 基本上分离无效字符的string,然后用空string重新join它们。

 - (IBAction)myTextFieldEditingChangedMethod:(UITextField *)sender { NSCharacterSet *validCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@".0123456789"]; NSCharacterSet *invalidCharacterSet = validCharacterSet.invertedSet; sender.text = [[sender.text componentsSeparatedByCharactersInSet:invalidCharacterSet] componentsJoinedByString:@""]; } 

积分: 删除NSString中的所有数字

在游戏后期,这里有一个方便的小类,它使用了小数位和用于它的本地符号。 链接到这里的要点

 @interface NSString (Extension) - (BOOL) isAnEmail; - (BOOL) isNumeric; @end @implementation NSString (Extension) /** * Determines if the current string is a valid email address. * * @return BOOL - True if the string is a valid email address. */ - (BOOL) isAnEmail { NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"; NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex]; return [emailTest evaluateWithObject:self]; } /** * Determines if the current NSString is numeric or not. It also accounts for the localised (Germany for example use "," instead of ".") decimal point and includes these as a valid number. * * @return BOOL - True if the string is numeric. */ - (BOOL) isNumeric { NSString *localDecimalSymbol = [[NSLocale currentLocale] objectForKey:NSLocaleDecimalSeparator]; NSMutableCharacterSet *decimalCharacterSet = [NSMutableCharacterSet characterSetWithCharactersInString:localDecimalSymbol]; [decimalCharacterSet formUnionWithCharacterSet:[NSCharacterSet alphanumericCharacterSet]]; NSCharacterSet* nonNumbers = [decimalCharacterSet invertedSet]; NSRange r = [self rangeOfCharacterFromSet: nonNumbers]; if (r.location == NSNotFound) { // check to see how many times the decimal symbol appears in the string. It should only appear once for the number to be numeric. int numberOfOccurances = [[self componentsSeparatedByString:localDecimalSymbol] count]-1; return (numberOfOccurances > 1) ? NO : YES; } else return NO; } @end 

海事组织最好的方式来实现你的目标是显示一个数字键盘,而不是普通的键盘。 这限制了哪些键可供用户使用。 这减轻了validation的需要,更重要的是防止用户犯错。 数字键盘input数字也好得多,因为键很大。

在界面构build器中selectUITextField,转到属性检查器并将“键盘types”更改为“小数点”。

在这里输入图像描述

这将使键盘看起来像这样:

在这里输入图像描述

剩下的唯一的事情就是确保用户不input两位小数。 编辑时你可以做这个。 将下面的代码添加到您的视图控制器。 该代码一旦input,就会删除第二个小数位。 用户看起来好像第二位小数从来没有出现在第一位。

 - (void)viewDidLoad { [super viewDidLoad]; [self.textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged]; } - (void)textFieldDidChange:(UITextField *)textField { NSString *text = textField.text; NSRange range = [text rangeOfString:@"."]; if (range.location != NSNotFound && [text hasSuffix:@"."] && range.location != (text.length - 1)) { // There's more than one decimal textField.text = [text substringToIndex:text.length - 1]; } } 
 @property (strong) NSNumberFormatter *numberFormatter; @property (strong) NSString *oldStringValue; - (void)awakeFromNib { [super awakeFromNib]; self.numberFormatter = [[NSNumberFormatter alloc] init]; self.oldStringValue = self.stringValue; [self setDelegate:self]; } - (void)controlTextDidChange:(NSNotification *)obj { NSNumber *number = [self.numberFormatter numberFromString:self.stringValue]; if (number) { self.oldStringValue = self.stringValue; } else { self.stringValue = self.oldStringValue; } } 
 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { if(string.length > 0) { NSCharacterSet *numbersOnly = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"]; NSCharacterSet *characterSetFromTextField = [NSCharacterSet characterSetWithCharactersInString:string]; BOOL stringIsValid = [numbersOnly isSupersetOfSet:characterSetFromTextField]; return stringIsValid; } return YES; } 

我想要一个只允许整数的文本字段。 以下是我结束了(使用从这里和其他地方的信息):

创build整数数字格式化程序(在UIApplicationDelegate中,以便重用):

 @property (nonatomic, retain) NSNumberFormatter *integerNumberFormatter; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Create and configure an NSNumberFormatter for integers integerNumberFormatter = [[NSNumberFormatter alloc] init]; [integerNumberFormatter setMaximumFractionDigits:0]; return YES; } 

在UITextFieldDelegate中使用filter:

 @interface MyTableViewController : UITableViewController <UITextFieldDelegate> { ictAppDelegate *appDelegate; } - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { // Make sure the proposed string is a number NSNumberFormatter *inf = [appDelegate integerNumberFormatter]; NSString* proposedString = [textField.text stringByReplacingCharactersInRange:range withString:string]; NSNumber *proposedNumber = [inf numberFromString:proposedString]; if (proposedNumber) { // Make sure the proposed number is an integer NSString *integerString = [inf stringFromNumber:proposedNumber]; if ([integerString isEqualToString:proposedString]) { // proposed string is an integer return YES; } } // Warn the user we're rejecting the change AudioServicesPlayAlertSound(kSystemSoundID_Vibrate); return NO; } 

不那么优雅,但简单:)

 - (BOOL) isNumber: (NSString*)input { return [input doubleValue] != 0 || [input isEqualToString:@"0"] || [input isEqualToString:@"0.0"]; } 

老线程,但值得一提的是,苹果在iOS 4.0中引入了NSRegularExpression 。 (从彼得的回答中得到正则expression式)

 // Look for 0-n digits from start to finish NSRegularExpression *noFunnyStuff = [NSRegularExpression regularExpressionWithPattern:@"^(?:|0|[1-9]\\d*)(?:\\.\\d*)?$" options:0 error:nil]; // There should be just one match if ([noFunnyStuff numberOfMatchesInString:<#theString#> options:0 range:NSMakeRange(0, <#theString#>.length)] == 1) { // Yay, digits! } 

我build议在某处存储NSRegularExpression实例。

在Swift 3中使用单个(。)点与iPad和iPhone一起工作的文本字段中接受小数值

  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 } } } 

为了更国际化(而不仅仅是美国的颜色;-))只需在上面的代码中replace

 -(NSNumber *) getNumber { NSString* localeIdentifier = [[NSLocale autoupdatingCurrentLocale] localeIdentifier]; NSLocale *l_en = [[NSLocale alloc] initWithLocaleIdentifier: localeIdentifier] ; return [self getNumberWithLocale: [l_en autorelease] ]; } 

如前所述,这个答案使用NSFormatter。 一探究竟:

 @interface NSString (NSNumber) - (BOOL) isNumberWithLocale:(NSLocale *) stringLocale; - (BOOL) isNumber; - (NSNumber *) getNumber; - (NSNumber *) getNumberWithLocale:(NSLocale*) stringLocale; @end @implementation NSString (NSNumber) - (BOOL) isNumberWithLocale:(NSLocale *) stringLocale { return [self getNumberWithLocale:stringLocale] != nil; } - (BOOL) isNumber { return [ self getNumber ] != nil; } - (NSNumber *) getNumber { NSLocale *l_en = [[NSLocale alloc] initWithLocaleIdentifier: @"en_US"] ; return [self getNumberWithLocale: [l_en autorelease] ]; } - (NSNumber *) getNumberWithLocale:(NSLocale*) stringLocale { NSNumberFormatter *formatter = [[ [ NSNumberFormatter alloc ] init ] autorelease]; [formatter setLocale: stringLocale ]; return [ formatter numberFromString:self ]; } @end 

我希望它可以帮助别人。 =)

  #import "NSString+Extension.h" //@interface NSString (Extension) // //- (BOOL) isAnEmail; //- (BOOL) isNumeric; // //@end @implementation NSString (Extension) - (BOOL) isNumeric { NSString *emailRegex = @"[0-9]+"; NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex]; return [emailTest evaluateWithObject:self]; // NSString *localDecimalSymbol = [[NSLocale currentLocale] objectForKey:NSLocaleDecimalSeparator]; // NSMutableCharacterSet *decimalCharacterSet = [NSMutableCharacterSet characterSetWithCharactersInString:localDecimalSymbol]; // [decimalCharacterSet formUnionWithCharacterSet:[NSCharacterSet alphanumericCharacterSet]]; // // NSCharacterSet* nonNumbers = [decimalCharacterSet invertedSet]; // NSRange r = [self rangeOfCharacterFromSet: nonNumbers]; // // if (r.location == NSNotFound) // { // // check to see how many times the decimal symbol appears in the string. It should only appear once for the number to be numeric. // int numberOfOccurances = [[self componentsSeparatedByString:localDecimalSymbol] count]-1; // return (numberOfOccurances > 1) ? NO : YES; // } // else return NO; } 

在Swift 4:

 let formatString = "12345" if let number = Decimal(string:formatString){ print("String contains only number") } else{ print("String doesn't contains only number") } 

这包括:小数部分控制(包括允许的小数位数),复制/粘贴控制,国际分隔符。

脚步:

  1. 确保你的视图控制器inheritance自UITextFieldDelegate

    类MyViewController:UIViewController,UITextFieldDelegate {…

  2. 在viewDidLoad中,将您的控件委托设置为self:

    重写func viewDidLoad(){super.viewDidLoad(); yourTextField.delegate = self}

  3. 实现下面的方法,并更新“decsAllowed”常量与所需的小数或0如果你想要一个自然数。

斯威夫特4

 func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { let decsAllowed: Int = 2 let candidateText = NSString(string: textField.text!).replacingCharacters(in: range, with: string) let decSeparator: String = NumberFormatter().decimalSeparator!; let splitted = candidateText.components(separatedBy: decSeparator) let decSeparatorsFound = splitted.count - 1 let decimalPart = decSeparatorsFound > 0 ? splitted.last! : "" let decimalPartCount = decimalPart.characters.count let characterSet = NSMutableCharacterSet.decimalDigit() if decsAllowed > 0 {characterSet.addCharacters(in: decSeparator)} let valid = characterSet.isSuperset(of: CharacterSet(charactersIn: candidateText)) && decSeparatorsFound <= 1 && decsAllowed >= decimalPartCount return valid } 

如果事后您需要安全地将该string转换为数字,则可以使用Double(yourstring)或Int(yourstring)types转换,或者更为学术的方式:

 let formatter = NumberFormatter() let theNumber: NSNumber = formatter.number(from: yourTextField.text)!