Sprawdź, czy dane wejściowe do UITextField są tylko liczbami

Odpowiedzi:

35

Używam tego kodu w mojej aplikacji na Maca, ten sam lub podobny powinien działać z iPhonem. Opiera się na wyrażeniach regularnych RegexKitLite i zmienia kolor tekstu na czerwony, gdy jest nieprawidłowy.

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]];
    }
}
Peter N Lewis
źródło
7
Tak, to okropnie stara odpowiedź, wiem, ale myślałem, że metody statyczne zostały zadeklarowane w ten sposób: + (BOOL) TextIsValidValue:(NSString*)newText:(double)&value:...
RCIX,
7
TextIsValidValue jest statyczną funkcją C, co oznacza, że ​​jest lokalna w pliku i nie jest częścią żadnego obiektu. Ty (@RCIX) opisujesz metodę obiektu, która jest podobna do metody statycznej w C ++ i jest zupełnie inną koncepcją niż statyczna funkcja C (lub statyczna zmienna o to chodzi!).
Peter N Lewis
Wyrażenie pasuje do pustego ciągu (który nie jest liczbą).
Nikolai Ruhe
Generalnie, aby dopasować liczbę do wejścia, musisz zezwolić na pusty łańcuch, w przeciwnym razie użytkownik nie może na przykład wpisać „1 <delete> 2”.
Peter N Lewis
6
Dla tych programistów, którzy nie wiedzą, czym są wyrażenia regularne ani jak działają, po prostu przejdź do tej witryny dekodera wyrażeń regularnych i skopiuj / wklej, (?:|0|[1-9]\\d*)(?:\\.\\d*)aby zobaczyć, co to oznacza. Zobacz także Regex Wikipedia
Honey
117

Możesz to zrobić w kilku linijkach w ten sposób:

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

- służy do sprawdzania poprawności danych wejściowych tylko znaków numerycznych. Zapoznaj się z dokumentacją dotyczącą NSCharacterSetinnych opcji. Możesz użyć characterSetWithCharactersInString, aby określić dowolny zestaw prawidłowych znaków wejściowych.

Donal O'Danachair
źródło
22
ta odpowiedź nie sprawdza podwójnych ani interpunkcyjnych
zambono
72

Możesz to zrobić na kilka sposobów:

  1. Użyj metody NSNumberFormatter numberFromString:. Zwróci to NSNumber, jeśli może poprawnie przeanalizować ciąg lub nilnie może.
  2. Użyj NSScanner
  3. Usuń wszystkie znaki nienumeryczne i sprawdź, czy ciąg nadal pasuje
  4. Użyj wyrażenia regularnego

IMO, użycie czegoś takiego jak -[NSString doubleValue]nie byłoby najlepszą opcją, ponieważ oba @"0.0"i @"abc"będą miały doubleValue równe 0. Wszystkie metody * value zwracają 0, jeśli nie są w stanie poprawnie przekonwertować ciągu, więc byłoby trudno rozróżnić prawidłowy ciąg @"0"i niepoprawny ciąg. Coś w rodzaju strtolfunkcji C miałoby ten sam problem.

Myślę, że użycie NSNumberFormatter byłoby najlepszą opcją, ponieważ bierze pod uwagę lokalizację (tj. Liczbę @"1,23"w Europie, w porównaniu @"1.23"z USA).

Dave DeLong
źródło
Hmmm, muszę ustawić opcje niepoprawnie dla NSNumberFormatter. Kiedy używam numberFromString, używając ciągu „34jfkjdskj80”, zwróci liczbę 3480. Wydaje się, że po prostu usuwa znaki zamiast zwracać zero.
Tony Eichelberger
5
@Tony yeah Nie jestem pewien, co robisz, ponieważ następujący dziennik „N: (null)” dla mnie:NSNumberFormatter * f = [[NSNumberFormatter alloc] init]; NSNumber * n = [f numberFromString:@"34jfkjdskj80"]; NSLog(@"N: %@", n);
Dave DeLong
2
To jest trochę stare, ale w przypadku, gdy ktoś to czyta, pomyślałem, że warto zauważyć, że podczas analizowania ciągu znaków, na NSScannerprzykład NSNumberFormatter, bierze pod uwagę ustawienia regionalne, pod warunkiem, że używasz setLocale:na obiekcie skanera (możesz na przykład podać [NSLocale currentLocale]).
dreamlax,
1
Niektórzy czytają „Wojna i pokój”. Inni wolą „Moby Dick”. Ja myślę, że zamierzam po prostu ściągnąć zestaw danych Stack Overflow, odfiltrować pytania z odpowiedziami Dave'a i po prostu cieszyć się.
BP.
1
@MarkAmery Tak, możesz polegać na tym zachowaniu. Chociaż może nie być udokumentowane, tak zachowywał się przez wiele lat, a zmiana tego byłaby niewykonalna z punktu widzenia zgodności binarnej.
Dave DeLong
19

Jeśli chcesz, aby użytkownik mógł wprowadzać tylko cyfry, możesz sprawić, by ViewController implementował część UITextFieldDelegate i zdefiniował tę metodę:

- (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];
}

Prawdopodobnie są bardziej wydajne sposoby, ale uważam, że jest to całkiem wygodny sposób. Metoda powinna być łatwa do dostosowania do walidacji podwójnych lub czegokolwiek innego: po prostu użyj scanDouble: lub podobnego.

Frank Shearar
źródło
13
#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;
}
kalpesh jetani
źródło
11

Oto kilka jednowierszowych, które łączą powyższą odpowiedź Petera Lewisa ( Sprawdź, czy dane wejściowe do UITextField są tylko liczbowe ) z 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]
Sai Ramachandran
źródło
Podaj mi link, z którego mogę dowiedzieć się więcej na ten temat.
Smit Saraiya
4

Dla testu liczb całkowitych będzie to:

- (BOOL) isIntegerNumber: (NSString*)input
{
    return [input integerValue] != 0 || [input isEqualToString:@"0"];
}
zvjerka24
źródło
Dobra odpowiedź, ale nadal problem z tym podejściem polegałby na tym, że wartość wejściowa „232asdfsadf” byłaby traktowana jako liczba.
Whoami,
można porównać długość wartości integerValue (ponownie przekonwertować na łańcuch) z oryginalnym ciągiem, aby upewnić się, że „123aoenuthr” nie jest traktowane jako liczba całkowita.
ThePrimeagen
3

Możesz użyć doubleValue swojego ciągu, na przykład

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

Myślę, że zwróci to wartość 0,0, jeśli łańcuch jest nieprawidłowy (może to spowodować zgłoszenie wyjątku, w którym to przypadku można go po prostu złapać, dokumentacja mówi, że jest to 0,0). więcej informacji tutaj

Daniel
źródło
Ponadto korzystanie z funkcji biblioteki jest zwykle lepsze niż skręcanie własnej. W tym przypadku inne kultury używają przecinka jako separatora dziesiętnego i prawdopodobnie biblioteki Cocoa sobie z tym poradzą.
kibibu
Nie wspominając robi dosłownych porównań równości pływak jest po prostu zła praktyka
M. Ryan
3

Cześć, miałem dokładnie ten sam problem i nie widzę odpowiedzi, której użyłem, opublikowanej, więc oto jest.

Stworzyłem i połączyłem swoje pole tekstowe przez IB. Kiedy połączyłem go z moim kodem za pomocą Control + Drag, wybrałem Action, a następnie wybrałem zdarzenie Editing Changed. Spowoduje to wyzwolenie metody przy każdym wpisie znaku. Możesz użyć innego zdarzenia.

Następnie użyłem tego prostego kodu, aby zastąpić tekst. Zwróć uwagę, że stworzyłem własny zestaw znaków zawierający znaki dziesiętne / kropki i liczby. Zasadniczo oddziela ciąg od nieprawidłowych znaków, a następnie łączy je ponownie z pustym ciągiem.

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

Kredyty: usuń wszystkie oprócz liczb z NSString

abc123
źródło
Liczby ujemne (-)?
CMVR
3

Spóźniona gra, ale tutaj przydatna mała kategoria, której używam, która uwzględnia miejsca dziesiętne i używany do tego lokalny symbol. link do jego istoty tutaj

@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
bennythemink
źródło
czy alfanumericCharacterSet nie powinien być decimalDigitCharacterSet w isNumeric? tak go używam.
Andrei Radulescu
Nie działa, @ „A” otrzymuje wynik numeryczny TAK, ale to nie jest liczba
Gank
3
- (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;
}
Hsm
źródło
3

IMO najlepszym sposobem na osiągnięcie celu jest wyświetlanie klawiatury numerycznej zamiast zwykłej klawiatury. Ogranicza to, które klucze są dostępne dla użytkownika. Zmniejsza to potrzebę przeprowadzania walidacji, a co ważniejsze, zapobiega popełnieniu błędu przez użytkownika. Klawiatura numeryczna jest również znacznie przyjemniejsza do wprowadzania cyfr, ponieważ klawisze są znacznie większe.

W konstruktorze interfejsu wybierz UITextField, przejdź do Inspektora atrybutów i zmień „Typ klawiatury” na „Pad dziesiętny”.

wprowadź opis obrazu tutaj

Dzięki temu klawiatura będzie wyglądać tak:

wprowadź opis obrazu tutaj

Pozostaje tylko upewnić się, że użytkownik nie wprowadza do dwóch miejsc po przecinku. Możesz to zrobić podczas edycji. Dodaj następujący kod do kontrolera widoku. Ten kod usuwa drugie miejsce po przecinku, gdy tylko zostanie wprowadzony. Wydaje się użytkownikowi, że 2. miejsce po przecinku nigdy nie pojawiło się na pierwszym miejscu.

- (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];
  }
}
David
źródło
1
nie zapomnij o możliwości kopiowania i wklejania - w tym przypadku twoje podejście zawodzi
slxl
1
Nie dotyczy to wszystkich przypadków. Użytkownik może skopiować wklejony tekst lub użyć klawiatury bluetooth.
fasola
2
@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;
  }
}
StuFF mc
źródło
2

Stary wątek, ale warto wspomnieć, że Apple wprowadziło NSRegularExpressioniOS 4.0. (Biorąc wyrażenie regularne z odpowiedzi Piotra)

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

Proponuję NSRegularExpressiongdzieś przechowywać instancję.

Mogą
źródło
1

Chciałem mieć pole tekstowe, które dopuszcza tylko liczby całkowite. Oto, na czym skończyłem (używając informacji z tego miejsca i gdzie indziej):

Utwórz program formatujący liczby całkowite (w UIApplicationDelegate, aby można go było ponownie wykorzystać):

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

Użyj filtra w 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;
}
Symetryczny
źródło
1

Nie tak elegancko, ale prosto :)

- (BOOL) isNumber: (NSString*)input
{
    return [input doubleValue] != 0 || [input isEqualToString:@"0"] || [input isEqualToString:@"0.0"];
}
zvjerka24
źródło
1
To rozwiązanie nie działa z nieskończonymi zerami, takimi jak 0,00. Więc nie będę sugerował ludziom korzystania z niego
Vinh,
1

Akceptuj wartości dziesiętne w polach tekstowych z pojedynczą (.) Kropką na iPadzie i iPhonie w 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
            }
        }
    }
Raj Joshi
źródło
0

Aby być bardziej międzynarodowym (i nie tylko w kolorze amerykańskim ;-)) po prostu zastąp w powyższym kodzie przez

-(NSNumber *) getNumber
{
  NSString* localeIdentifier = [[NSLocale autoupdatingCurrentLocale] localeIdentifier];
  NSLocale *l_en = [[NSLocale alloc] initWithLocaleIdentifier: localeIdentifier] ;
  return [self getNumberWithLocale: [l_en autorelease] ];
}
user1458963
źródło
0

Ta odpowiedź używa NSFormatter, jak wspomniano wcześniej. Sprawdź to:

@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

Mam nadzieję, że to komuś pomoże. =)

Leandro
źródło
0
   #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;
    }
Gank
źródło
0

W Swift 4:

let formatString = "12345"
if let number = Decimal(string:formatString){

    print("String contains only number")
}
else{
    print("String doesn't contains only number")
}
Ankit garg
źródło
0

Obejmuje to: kontrolę części dziesiętnej (w tym dozwoloną liczbę miejsc po przecinku), kontrolę kopiowania / wklejania, separatory międzynarodowe.

Kroki:

  1. Upewnij się, że kontroler widoku dziedziczy po UITextFieldDelegate

    klasa MyViewController: UIViewController, UITextFieldDelegate {...

  2. W viewDidLoad ustaw delegata kontroli na siebie:

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

  3. Zaimplementuj następującą metodę i zaktualizuj stałą „decsAllowed” o żądaną liczbę miejsc po przecinku lub 0, jeśli chcesz uzyskać liczbę naturalną.

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

Jeśli później chcesz bezpiecznie przekonwertować ten ciąg na liczbę, możesz po prostu użyć rzutowania typu Double (yourstring) lub Int (yourstring) lub w bardziej akademicki sposób:

let formatter = NumberFormatter()
let theNumber: NSNumber = formatter.number(from: yourTextField.text)!
Jorge Ramírez
źródło