2012-02-28 9 views
9

En UITextField Entramos Sólo Numérico y limitar hasta 3 numérico para esto he utilizado a continuación código¿Cómo ingresar números solo en UITextField y limitar la longitud máxima?

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

} 

cuando pulso pulsación larga en el campo de texto (como por debajo de la imagen) y entrar en la cadena entre dos números que está permitiendo que todos los caracteres especiales y fletadores también. enter image description here

+0

puede utilizar expresiones regulares para que –

+0

[Esta respuesta] (http://stackoverflow.com/a/8370624/927947) debería ayudar. Posible engańo. – NJones

Respuesta

40

No es que no me gusta the answer I wrote at this question, que era copy & pasted aquí también. Trataré de explicar tu error.

Esta respuesta se basa en la suposición de que sus constantes se definen así:

#define NUMBERS_ONLY @"1234567890" 
#define CHARACTER_LIMIT 3 

La razón lógica está fallando es que nunca se controla el evento cuando newLength será igual a la CHARACTER_LIMIT.

Para ilustrar suponga que su campo de texto está vacío y solicita pegar la cadena @"ABC" en el campo de texto, se llamará a su método de delegado. Crea la cadena filtered que evalúa correctamente una cadena vacía y no puede esperar para ejecutar la línea return [string isEqualToString:filtered]; pero nunca evalúa esa línea porque no cumple con los requisitos de entrada para el ciclo while, porque newLength es 3. entonces el simple return (newLength > CHARACTER_LIMIT) ? NO : YES; decide el valor de retorno.

Si su CHARACTER_LIMIT es actualmente 4 por alguna razón, imagine @"ABCD" como la cadena que aún aplica la lógica.

Aquí hay un ejemplo simple de su función corregida para funcionar. Una vez más estoy suponiendo que CHARACTER_LIMIT es igual a 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

¡Muchas gracias! – Magurizio

+0

¿podría usar [NSCharacterSet decimalDigitCharacterSet] en su lugar? –

0

Comprobar la UITextFieldDelegate método

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

Este método será invocado cada vez que después de escribir/pulse un carácter o presione cortar/pegar y antes de que la acción cambia los caracteres de la imagen. Aquí puede hacer un chequeo para el máximo de longitud y el ingreso de texto de solo números (usando el patrón RegularExpression como se indica a continuación) y devolver SÍ o NO basándose en eso. Si devuelve SÍ, hará el cambio; de lo contrario, no lo hará. Espero que esto aclare tu duda.

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

Su funcionamiento muy bien para mí u puede utilizar este código

+0

Sí. es un código bueno y funcional. –

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

Yo prefiero usar un NSNumberFormatter para validar el texto se puede analizar en un número. NSNumberFormatter devuelve nil si la cadena no se puede convertir a un número. Esto le permite reaccionar a la entrada (es decir, hacer que el texto rojo, lanzar un alerta)

NSNumber* value = nil; 
NSNumberFormatter* format = [[NSNumberFormatter alloc] init]; 
value = [format numberFromString:someValueString];//returns and 
if (value == nil){ 
    //do something useful i.e. show alert 
} 
Cuestiones relacionadas