2012-02-28 19 views
9

W UITextField wchodzimy tylko numeryczne i ograniczyć do 3 liczbową tego użyłem poniżej kodJak wpisać liczby tylko w UITextField i ograniczyć maksymalną długość?

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

} 

po naciśnięciu długie naciśnięcie na polu tekstowym (jak poniżej obrazu) i wprowadź ciąg pomiędzy dwoma numerami to pozwalając wszystkie znaki specjalne i czarterujący również. enter image description here

+0

można użyć wyrażenia regularnego dla tego –

+0

[Ta odpowiedź] (http://stackoverflow.com/a/8370624/927947) powinno pomóc. Możliwe dupe. – NJones

Odpowiedz

40

Nie, że mi się nie podoba the answer I wrote at this question, że był copy & pasted tutaj również. Spróbuję wyjaśnić twój błąd.

Ta odpowiedź jest oparta na założeniu, że stałe są zdefiniowane tak:

#define NUMBERS_ONLY @"1234567890" 
#define CHARACTER_LIMIT 3 

Powodem logika zawodzi jest to, że nigdy nie można obsłużyć zdarzenie gdy newLength będzie równa CHARACTER_LIMIT.

Aby to zilustrować, załóżmy, że twoje pole tekstowe jest puste i chcesz wkleić ciąg tekstowy @"ABC" do pola tekstowego, zostanie wywołana metoda delegata. Tworzysz ciąg znaków filtered, który poprawnie analizuje pusty łańcuch, i nie możesz się doczekać, aż wykonasz linię return [string isEqualToString:filtered];, ale nigdy nie ocenisz tej linii, ponieważ nie spełniasz wymagań wejściowych dla pętli while, ponieważ newLength ma wartość 3. więc prosty return (newLength > CHARACTER_LIMIT) ? NO : YES; decyduje o wartości zwracanej.

Jeśli Twój CHARACTER_LIMIT jest w rzeczywistości 4 z jakiegoś powodu, po prostu wyobraź sobie, że @"ABCD" jest ciągiem, który nadal obowiązuje.

Oto prosty przykład poprawionej funkcji. Znowu jestem przy założeniu, że CHARACTER_LIMIT jest równy 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)); 
} 
+0

Dziękuję bardzo! – Magurizio

+0

można zamiast tego użyć [NSCharacterSet decimalDigitCharacterSet]? –

0

Sprawdź metodę

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

UITextFieldDelegate Ta metoda będzie wywoływana za każdym razem po wpisaniu/dotknij znaku lub naciśnij wytnij/wklej i przed zmianami, które działanie znaków wyświetlany. Tutaj można bardzo dobrze sprawdzić, czy wprowadzane są dane tekstowe maxLength i liczbowe (przy użyciu poniższego wzorca funkcji RegularExpression) i zwracać TAK lub NIE w tym przypadku. Jeśli zwrócisz TAK, spowoduje to zmianę, inaczej nie będzie. Mam nadzieję, że to rozwiąże twoje wątpliwości.

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

grzywny działa na mnie u można użyć tego kodu

+0

Tak. jego dobry i działający kod. –

1
- (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); 
} 
0

Wolę używając NSNumberFormatter do sprawdzania tekstu może być analizowany pod numerem. NSNumberFormatter zwraca zero, jeśli ciąg nie może zostać przekonwertowany na liczbę. To pozwala reagować na wejście (czyli dokonać czerwonym tekstem, rzucać się 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 
} 
Powiązane problemy