Wie überprüfe ich die Zeichenfolgeneingabe für a UITextField
? Ich möchte überprüfen, ob die Zeichenfolge numerisch ist, einschließlich Dezimalstellen.
Wie überprüfe ich die Zeichenfolgeneingabe für a UITextField
? Ich möchte überprüfen, ob die Zeichenfolge numerisch ist, einschließlich Dezimalstellen.
Antworten:
Ich verwende diesen Code in meiner Mac-App. Der gleiche oder ein ähnlicher Code sollte mit dem iPhone funktionieren. Es basiert auf den regulären RegexKitLite-Ausdrücken und färbt den Text rot, wenn er ungültig ist.
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*)
zu sehen, was es bedeutet. Siehe auch Regex Wikipedia
Sie können es in ein paar Zeilen wie folgt tun:
BOOL valid;
NSCharacterSet *alphaNums = [NSCharacterSet decimalDigitCharacterSet];
NSCharacterSet *inStringSet = [NSCharacterSet characterSetWithCharactersInString:myInputField.text];
valid = [alphaNums isSupersetOfSet:inStringSet];
if (!valid) // Not numeric
- Dies dient zur Überprüfung der Eingabe nur mit numerischen Zeichen. NSCharacterSet
Weitere Optionen finden Sie in der Dokumentation . Mit characterSetWithCharactersInString können Sie einen beliebigen Satz gültiger Eingabezeichen angeben.
Es gibt einige Möglichkeiten, wie Sie dies tun können:
nil
nicht.IMO, die Verwendung von so etwas -[NSString doubleValue]
wäre nicht die beste Option, da beide @"0.0"
und @"abc"
einen doubleValue von 0 haben. Die * value-Methoden geben alle 0 zurück, wenn sie den String nicht richtig konvertieren können, sodass es schwierig wäre, zwischen a zu unterscheiden legitime Zeichenfolge von @"0"
und eine ungültige Zeichenfolge. So etwas wie die strtol
Funktion von C hätte das gleiche Problem.
Ich denke, die Verwendung von NSNumberFormatter wäre die beste Option, da das Gebietsschema berücksichtigt wird (dh die Anzahl @"1,23"
in Europa im Vergleich @"1.23"
zu den USA).
NSNumberFormatter * f = [[NSNumberFormatter alloc] init]; NSNumber * n = [f numberFromString:@"34jfkjdskj80"]; NSLog(@"N: %@", n);
NSScanner
, wie NSNumberFormatter
, locale berücksichtigt , wenn die Zeichenfolge Parsen, vorausgesetzt , Sie verwenden setLocale:
auf dem Scanner - Objekt (Sie könnten zum Beispiel bieten [NSLocale currentLocale]
).
Wenn Sie möchten, dass ein Benutzer nur Zahlen eingeben darf, können Sie Ihren ViewController-Teil von UITextFieldDelegate implementieren lassen und diese Methode definieren:
- (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];
}
Es gibt wahrscheinlich effizientere Wege, aber ich finde das ziemlich bequem . Und die Methode sollte leicht an die Validierung von Doppelbildern oder was auch immer anpassbar sein: Verwenden Sie einfach scanDouble: oder ähnliches.
#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;
}
Hier sind einige Einzeiler, die die obige Antwort von Peter Lewis ( Überprüfen Sie, ob eine Eingabe in UITextField nur numerisch ist ) mit NSPredicates kombinieren
#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]
Für einen ganzzahligen Test ist es:
- (BOOL) isIntegerNumber: (NSString*)input
{
return [input integerValue] != 0 || [input isEqualToString:@"0"];
}
Sie können den doubleValue Ihres Strings wie verwenden
NSString *string=@"1.22";
double a=[string doubleValue];
Ich denke, dies wird eine als 0.0 zurückgeben, wenn die Zeichenfolge ungültig ist (es könnte eine Ausnahme auslösen, in diesem Fall können Sie es einfach abfangen, die Dokumente sagen 0.0 tho). Mehr Infos hier
Hallo, hatte genau das gleiche Problem und ich sehe die Antwort, die ich verwendet habe, nicht. Also hier ist sie.
Ich habe mein Textfeld über IB erstellt und verbunden. Als ich es über Strg + Ziehen mit meinem Code verbunden habe, habe ich Aktion ausgewählt und dann das Ereignis Bearbeiten geändert ausgewählt. Dies löst die Methode bei jeder Zeicheneingabe aus. Sie können ein anderes Ereignis verwenden, um zu passen.
Danach habe ich diesen einfachen Code verwendet, um den Text zu ersetzen. Beachten Sie, dass ich meinen eigenen Zeichensatz erstellt habe, der das Dezimal- / Punktzeichen und die Zahlen enthält. Trennt im Grunde die Zeichenfolge von den ungültigen Zeichen und verbindet sie dann mit einer leeren Zeichenfolge.
- (IBAction)myTextFieldEditingChangedMethod:(UITextField *)sender {
NSCharacterSet *validCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@".0123456789"];
NSCharacterSet *invalidCharacterSet = validCharacterSet.invertedSet;
sender.text = [[sender.text componentsSeparatedByCharactersInSet:invalidCharacterSet] componentsJoinedByString:@""];
}
Spät zum Spiel, aber hier eine praktische kleine Kategorie, die Dezimalstellen und das dafür verwendete lokale Symbol berücksichtigt. Link zu seinem Kern hier
@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 Der beste Weg, um Ihr Ziel zu erreichen, ist die Anzeige einer numerischen Tastatur anstelle der normalen Tastatur. Dies schränkt ein, welche Schlüssel dem Benutzer zur Verfügung stehen. Dies verringert die Notwendigkeit einer Validierung und verhindert vor allem, dass der Benutzer einen Fehler macht. Der Nummernblock eignet sich auch viel besser zur Eingabe von Nummern, da die Tasten wesentlich größer sind.
Wählen Sie im Interface Builder das UITextField aus, rufen Sie den Attributes Inspector auf und ändern Sie den "Tastaturtyp" in "Decimal Pad".
Dadurch sieht die Tastatur folgendermaßen aus:
Sie müssen nur noch sicherstellen, dass der Benutzer keine zwei Dezimalstellen eingibt. Sie können dies tun, während sie bearbeiten. Fügen Sie Ihrem View Controller den folgenden Code hinzu. Dieser Code entfernt eine zweite Dezimalstelle, sobald er eingegeben wird. Dem Benutzer erscheint es so, als ob die 2. Dezimalstelle überhaupt nicht erschienen wäre.
- (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;
}
}
Alter Thread, aber es ist erwähnenswert, dass Apple NSRegularExpression
in iOS 4.0 eingeführt hat. (Den regulären Ausdruck aus Peters Antwort nehmen)
// 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!
}
Ich schlage vor, die NSRegularExpression
Instanz irgendwo zu speichern .
Ich wollte ein Textfeld, das nur ganze Zahlen zulässt. Folgendes habe ich erreicht (unter Verwendung von Informationen von hier und anderswo):
Erstellen Sie einen Ganzzahlformatierer (in UIApplicationDelegate, damit er wiederverwendet werden kann):
@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;
}
Verwenden Sie den Filter in 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;
}
Nicht so elegant, aber einfach :)
- (BOOL) isNumber: (NSString*)input
{
return [input doubleValue] != 0 || [input isEqualToString:@"0"] || [input isEqualToString:@"0.0"];
}
Akzeptieren Sie Dezimalwerte in Textfeldern mit einem einzelnen (.) Punkt, die mit iPad und iPhone in Swift 3 funktionieren
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
}
}
}
Um internationaler zu sein (und nicht nur in den USA ;-)), ersetzen Sie einfach den obigen Code durch
-(NSNumber *) getNumber
{
NSString* localeIdentifier = [[NSLocale autoupdatingCurrentLocale] localeIdentifier];
NSLocale *l_en = [[NSLocale alloc] initWithLocaleIdentifier: localeIdentifier] ;
return [self getNumberWithLocale: [l_en autorelease] ];
}
Diese Antwort verwendet NSFormatter wie zuvor erwähnt. Hör zu:
@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
Ich hoffe es hilft jemandem. =)
#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;
}
In Swift 4:
let formatString = "12345"
if let number = Decimal(string:formatString){
print("String contains only number")
}
else{
print("String doesn't contains only number")
}
Dies umfasst: Dezimalteilsteuerung (einschließlich der Anzahl der zulässigen Dezimalstellen), Kopier- / Einfügekontrolle, internationale Trennzeichen.
Schritte:
Stellen Sie sicher, dass Ihr View Controller von UITextFieldDelegate erbt
Klasse MyViewController: UIViewController, UITextFieldDelegate {...
Setzen Sie in viewDidLoad Ihren Steuerelementdelegierten auf self:
überschreiben func viewDidLoad () {super.viewDidLoad (); yourTextField.delegate = self}
Implementieren Sie die folgende Methode und aktualisieren Sie die Konstante "decsAllowed" mit der gewünschten Anzahl von Dezimalstellen oder 0, wenn Sie eine natürliche Zahl wünschen.
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
}
Wenn Sie diese Zeichenfolge anschließend sicher in eine Zahl umwandeln müssen, können Sie einfach die Besetzung vom Typ Double (Ihre Zeichenfolge) oder Int (Ihre Zeichenfolge) oder die akademischere Methode verwenden:
let formatter = NumberFormatter()
let theNumber: NSNumber = formatter.number(from: yourTextField.text)!
+ (BOOL) TextIsValidValue:(NSString*)newText:(double)&value:
...