에 대한 문자열 입력의 유효성을 어떻게 확인 UITextField
합니까? 문자열이 소수점을 포함하여 숫자인지 확인하고 싶습니다.
답변:
이 코드를 Mac 앱에서 사용합니다. 동일하거나 유사한 코드가 iPhone에서도 작동합니다. RegexKitLite 정규식을 기반으로하며 유효하지 않은 경우 텍스트를 빨간색으로 바꿉니다.
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]];
}
}
(?:|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
그렇지 않은 경우 NSNumber를 반환합니다 .IMO, 같은 것을 사용하는 것이 -[NSString doubleValue]
최선의 선택을하지 않을 것입니다 모두 때문에 @"0.0"
그리고 @"abc"
그들은 구별하기 어려울 것이다, 그래서 제대로 문자열을 변환 할 수없는 경우 * 값 방법에게 0의 모든 반환 0있는 doubleValue이있을 것이다 의 합법적 인 문자열 @"0"
과 유효하지 않은 문자열입니다. C의 strtol
기능 과 같은 것에는 동일한 문제가 있습니다.
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;
}
다음은 위의 Peter Lewis의 답변 ( 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]
다음과 같이 문자열의 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;
}
IMO는 목표를 달성하는 가장 좋은 방법은 일반 키보드가 아닌 숫자 키보드를 표시하는 것입니다. 이것은 사용자가 사용할 수있는 키를 제한합니다. 이렇게하면 유효성 검사의 필요성이 줄어들고 더 중요한 것은 사용자의 실수를 방지하는 것입니다. 숫자 패드는 키가 상당히 크기 때문에 숫자를 입력 할 때 훨씬 더 좋습니다.
인터페이스 빌더에서 UITextField를 선택하고 Attributes Inspector로 이동하여 "Keyboard Type"을 "Decimal Pad"로 변경합니다.
그러면 키보드가 다음과 같이 보입니다.
남은 것은 사용자가 소수점 둘째 자리에 입력하지 않도록하는 것입니다. 편집하는 동안이 작업을 수행 할 수 있습니다. 뷰 컨트롤러에 다음 코드를 추가합니다. 이 코드는 입력하자마자 소수점 둘째 자리를 제거합니다. 사용자에게는 두 번째 소수점이 처음에 나타나지 않은 것처럼 보입니다.
- (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에 도입했다는 점은 언급 할 가치가 있습니다. (Peter의 응답에서 정규식 가져 오기)
// 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;
}
Swift 3에서 iPad 및 iPhone에서 작동하는 단일 (.) 점이있는 텍스트 필드의 10 진수 값 허용
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;
}
여기에는 소수점 부분 제어 (허용되는 소수점 수 포함), 복사 / 붙여 넣기 제어, 국제 구분 기호가 포함됩니다.
단계 :
뷰 컨트롤러가 UITextFieldDelegate에서 상속되는지 확인하십시오.
class MyViewController : UIViewController, UITextFieldDelegate {...
viewDidLoad에서 제어 대리자를 self로 설정합니다.
func 재정의 viewDidLoad () {super.viewDidLoad (); yourTextField.delegate = self}
다음 메서드를 구현하고 "decsAllowed"상수를 원하는 소수 자릿수로 업데이트하거나 자연수가 필요한 경우 0으로 업데이트합니다.
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)!
+ (BOOL) TextIsValidValue:(NSString*)newText:(double)&value:
...