Как мне проверить ввод строки в a UITextField
? Я хочу проверить, является ли строка числовой, включая десятичные точки.
objective-c
cocoa-touch
validation
nsstring
uitextfield
g.революция
источник
источник
+ (BOOL) TextIsValidValue:(NSString*)newText:(double)&value:
...(?:|0|[1-9]\\d*)(?:\\.\\d*)
чтобы увидеть, что это означает. Также см. Regex WikipediaВы можете сделать это в нескольких строках, например:
BOOL valid; NSCharacterSet *alphaNums = [NSCharacterSet decimalDigitCharacterSet]; NSCharacterSet *inStringSet = [NSCharacterSet characterSetWithCharactersInString:myInputField.text]; valid = [alphaNums isSupersetOfSet:inStringSet]; if (!valid) // Not numeric
- это для проверки ввода только числовых символов. Прочтите документацию, чтобы
NSCharacterSet
узнать о других вариантах. Вы можете использовать characterSetWithCharactersInString, чтобы указать любой набор допустимых входных символов.источник
Есть несколько способов сделать это:
nil
не может.IMO, используя что - то вроде
-[NSString doubleValue]
бы не самый лучший вариант , потому что как@"0.0"
и@"abc"
будет иметь doubleValue от 0. * Методы значение , все возвращаются 0 , если они не в состоянии преобразовать строку правильно, поэтому было бы трудно отличить допустимая строка@"0"
и недопустимая строка. Что-то вродеstrtol
функции C будет иметь ту же проблему.Я думаю, что использование NSNumberFormatter было бы лучшим вариантом, поскольку он принимает во внимание локаль (т. Е. Число
@"1,23"
в Европе, а не@"1.23"
в США).источник
NSNumberFormatter * f = [[NSNumberFormatter alloc] init]; NSNumber * n = [f numberFromString:@"34jfkjdskj80"]; NSLog(@"N: %@", n);
NSScanner
вроде быNSNumberFormatter
учитывает языковой стандарт при синтаксическом анализе строки, при условии, что вы используетеsetLocale:
объект сканера (вы могли бы, например, предоставить[NSLocale currentLocale]
).Если вы хотите, чтобы пользователю было разрешено вводить только цифры, вы можете заставить 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]; }
Возможно, есть более эффективные способы, но я считаю это довольно удобным . И метод должен быть легко адаптирован для проверки двойников или чего-то еще: просто используйте 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; }
источник
Вот несколько однострочников, которые объединяют ответ Питера Льюиса выше ( убедитесь, что вход в UITextField является только числовым ) с 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]
источник
Для целочисленного теста это будет:
- (BOOL) isIntegerNumber: (NSString*)input { return [input integerValue] != 0 || [input isEqualToString:@"0"]; }
источник
Вы можете использовать doubleValue своей строки, например
NSString *string=@"1.22"; double a=[string doubleValue];
Я думаю, что это вернет значение 0,0, если строка недействительна (это может вызвать исключение, и в этом случае вы можете просто поймать его, в документации указано 0,0 tho). подробнее здесь
источник
У меня была точно такая же проблема, и я не вижу ответ, который я опубликовал, так что вот он.
Я создал и подключил свое текстовое поле через IB. Когда я подключил его к своему коду с помощью Control + Drag, я выбрал Action, а затем выбрал событие Editing Changed. Это запускает метод для каждого ввода символа. Вы можете использовать другое мероприятие по своему усмотрению.
Впоследствии я использовал этот простой код для замены текста. Обратите внимание, что я создал свой собственный набор символов, включающий десятичный / периодический символ и числа. В основном разделяет строку на недопустимые символы, а затем объединяет их с пустой строкой.
- (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
источник
- (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; }
источник
ИМО лучший способ достичь вашей цели - отобразить цифровую клавиатуру, а не обычную клавиатуру. Это ограничивает, какие ключи доступны пользователю. Это устраняет необходимость в проверке и, что еще более важно, предотвращает ошибку пользователя. Цифровая клавиатура также намного удобнее для ввода цифр, потому что клавиши значительно больше.
В построителе интерфейса выберите UITextField, перейдите в Инспектор атрибутов и измените «Тип клавиатуры» на «Десятичный блокнот».
В результате клавиатура будет выглядеть так:
Осталось только убедиться, что пользователь не вводит два десятичных знака. Вы можете сделать это, пока они редактируют. Добавьте следующий код в свой контроллер представления. Этот код удаляет второй десятичный разряд сразу после его ввода. Пользователю кажется, что второй знак после запятой никогда не появлялся.
- (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; } }
источник
Старая ветка, но стоит упомянуть, что Apple представила
NSRegularExpression
iOS 4.0. (Взяв регулярное выражение из ответа Питера)// 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! }
Предлагаю
NSRegularExpression
где-нибудь хранить экземпляр.источник
Мне нужно текстовое поле, в котором разрешены только целые числа. Вот что у меня получилось (используя информацию отсюда и из других источников):
Создайте средство форматирования целых чисел (в 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:
@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"]; }
источник
Принимать десятичные значения в текстовых полях с одинарной точкой (.) При работе с iPad и iPhone в 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 } } }
источник
Чтобы быть более интернациональным (и не только американским ;-)), просто замените в приведенном выше коде на
-(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") }
источник
Это включает: управление десятичной частью (включая количество разрешенных десятичных знаков), управление копированием / вставкой, международные разделители.
Шаги:
Убедитесь, что ваш контроллер представления наследуется от UITextFieldDelegate
класс MyViewController: UIViewController, UITextFieldDelegate {...
В viewDidLoad установите для своего управляющего делегата self:
переопределить функцию viewDidLoad () {super.viewDidLoad (); yourTextField.delegate = self}
Реализуйте следующий метод и обновите константу decsAllowed с желаемым количеством десятичных знаков или 0, если вы хотите натуральное число.
Swift 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 }
Если после этого вам нужно безопасно преобразовать эту строку в число, вы можете просто использовать приведение типа Double (yourstring) или Int (yourstring) или более академическим способом:
let formatter = NumberFormatter() let theNumber: NSNumber = formatter.number(from: yourTextField.text)!
источник