Jak wprowadzić liczby tylko w UITextField i ograniczyć maksymalną długość?

W UITextField wpisujemy tylko numeryczne i ograniczamy do 3 numeryczne do tego użyłem poniższego kodu

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string  {


    NSUInteger newLength = [textField.text length] + [string length] - range.length;

    NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:NUMBERS_ONLY] invertedSet];

    NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];

    while (newLength < CHARACTER_LIMIT) {
        return [string isEqualToString:filtered];
    }

/* Limits the no of characters to be enter in text field */

    return (newLength > CHARACTER_LIMIT ) ? NO : YES; 

}

Kiedy nacisnę long naciśnij na textfield (jak na poniższym obrazku) i wprowadź ciąg pomiędzy dwoma liczbami to pozwala na wszystkie znaki specjalne i charterers również. Tutaj wpisz opis obrazka

Author: Maulik, 2012-02-28

5 answers

Nie to, że nie podoba mi się odpowiedź, którą napisałem na to pytanie , to było skopiuj i wklej tutaj również. Postaram się wyjaśnić twój błąd.

Ta odpowiedź opiera się na założeniu, że Twoje stałe są zdefiniowane mniej więcej tak:

#define NUMBERS_ONLY @"1234567890"
#define CHARACTER_LIMIT 3

Powodem, dla którego twoja logika zawodzi, jest to, że nigdy nie zajmujesz się zdarzeniem, gdy newLength będzie równe CHARACTER_LIMIT.

Aby zilustrować Załóżmy, że pole tekstowe jest puste i prosimy o wklejenie ciągu @"ABC" do textfield, zostanie wywołana twoja metoda delegata. Tworzysz łańcuch filtered, który poprawnie przekształca się w pusty łańcuch i nie możesz się doczekać uruchomienia linii return [string isEqualToString:filtered];, ale nigdy nie oceniasz tej linii, ponieważ nie spełniasz wymagań wejściowych dla pętli while, ponieważ newLength jest 3. tak więc prosta return (newLength > CHARACTER_LIMIT ) ? NO : YES; decyduje o zwracanej wartości.

Jeśli {[3] } jest rzeczywiście 4 z jakiegoś powodu, po prostu wyobraź sobie @"ABCD" jako ciąg logiki nadal stosuje.

Oto prosty przykład twoja funkcja poprawiona do pracy. Ponownie zakładam, że {[3] } jest równe 3.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string  {
    NSUInteger newLength = [textField.text length] + [string length] - range.length;
    NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:NUMBERS_ONLY] invertedSet];
    NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
    return (([string isEqualToString:filtered])&&(newLength <= CHARACTER_LIMIT));
}
 40
Author: NJones,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:30:24
 -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
    // Check for non-numeric characters
    NSUInteger lengthOfString = string.length;
    for (NSInteger loopIndex = 0; loopIndex < lengthOfString; loopIndex++) {
        unichar character = [string characterAtIndex:loopIndex];
        if (character < 48) return NO; // 48 unichar for 0
        if (character > 57) return NO; // 57 unichar for 9
    }
    // Check for total length
    NSUInteger proposedNewLength = textField.text.length - range.length + string.length;
    if (proposedNewLength > 3) return NO;
    return YES;
    }

Its working fine for me u can use this code

 5
Author: Rama Rao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-28 09:08:05
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    NSString *s = [textField.text stringByReplacingCharactersInRange:range withString:string];
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^\\d{0,3}$" options:0 error:nil];
    NSTextCheckingResult *match = [regex firstMatchInString:s options:0 range:NSMakeRange(0, [s length])];
    return (match != nil);
}
 1
Author: neoneye,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-28 08:10:55

Sprawdź metodę UITextFieldDelegate

- (BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {

Ta metoda będzie wywoływana każdorazowo po wpisaniu / dotknięciu znaku lub naciśnięciu przycisku Wytnij / Wklej i przed tą akcją zmieni się wyświetlane znaki. Tutaj można bardzo dobrze sprawdzić maxlength i numbers-tylko tekst wprowadzania (za pomocą RegularExpression patter jak podano poniżej) i zwracać tak lub nie basd na tym. Jeśli zwrócisz tak, zrobi to zmiana, w przeciwnym razie nie. Mam nadzieję, że to rozwiąże Twoje wątpliwości.

 0
Author: durai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-28 09:06:53

Wolę używać NSNumberFormatter do walidacji tekstu może być parsowany do liczby. NSNumberFormatter zwraca nil, jeśli łańcuch nie może być przekonwertowany na liczbę. Dzięki temu możesz reagować na dane wejściowe (np. zmienić tekst na czerwony, wywołać alert)

NSNumber* value = nil;
NSNumberFormatter* format = [[NSNumberFormatter alloc] init];
value  = [format numberFromString:someValueString];//returns and
if (value == nil){
    //do something useful i.e. show alert
}
 0
Author: Todd Lahtinen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-27 15:20:00