Как ввести числа только в UITextField и ограничить максимальную длину? - PullRequest
9 голосов
/ 28 февраля 2012

В UITextField мы вводим только цифру и ограничиваем до 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:@""];

    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; 

}

Когда я нажимаю долгое нажатие на текстовое поле (как на картинке ниже) и вводим строку между двумя числами, это позволяетвсе специальные персонажи и фрахтователи также.enter image description here

Ответы [ 5 ]

40 голосов
/ 29 февраля 2012

Не то, чтобы мне не нравился ответ, который я написал на этот вопрос , который был скопировать и вставить и здесь. Я постараюсь объяснить вашу ошибку.

Этот ответ основан на предположении, что ваши константы определены примерно так:

#define NUMBERS_ONLY @"1234567890"
#define CHARACTER_LIMIT 3

Причина, по которой ваша логика не работает, состоит в том, что вы никогда не обрабатываете событие, когда newLength будет равно CHARACTER_LIMIT.

Чтобы проиллюстрировать, что ваше текстовое поле пусто, и вы запрашиваете вставить строку @"ABC" в текстовое поле, вызывается ваш метод делегата. Вы создаете строку filtered, которая правильно оценивается как пустую строку, и вы не можете дождаться выполнения строки return [string isEqualToString:filtered];, но на самом деле вы никогда не оцениваете эту строку, потому что вы не соответствуете требованиям входа для цикла while, потому что newLength равно 3. таким образом, простое return (newLength > CHARACTER_LIMIT ) ? NO : YES; решает возвращаемое значение.

Если ваш CHARACTER_LIMIT по какой-то причине равен 4, просто представьте @"ABCD" как строку, к которой все еще применяется логика.

Вот простой пример исправления вашей функции для работы. Я опять предполагаю, что CHARACTER_LIMIT равно 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));
}
5 голосов
/ 28 февраля 2012
 -(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;
    }

Это нормально работает, вы можете использовать этот код

1 голос
/ 28 сентября 2012
- (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 голосов
/ 27 февраля 2015

Я предпочитаю использовать NSNumberFormatter для проверки того, что текст можно разобрать в число.NSNumberFormatter возвращает nil, если строка не может быть преобразована в число.Это позволяет вам реагировать на ввод (т.е. сделать текст красным, вывести предупреждение)

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 голосов
/ 28 февраля 2012

Проверьте метод UITextFieldDelegate

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

Этот метод будет вызываться каждый раз после того, как вы введете / коснитесь символа или нажмете вырезать / вставить и перед тем, как это действие изменит отображаемые символы. Здесь вы можете очень хорошо проверить ваш текст для ввода maxLength и только для чисел (используя шаблон RegularExpression, как указано ниже) и вернуть YES или NO, основываясь на этом. Если вы вернете ДА, он внесет изменения, иначе не будет. Надеюсь, это очистит ваши сомнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...