Filtrar caracteres ingresados ??en un UITextField
-
06-07-2019 - |
Pregunta
Tengo un UITextField en mi aplicación. Me gustaría restringir el conjunto de caracteres que pueden ingresarse en el campo a un conjunto que he definido. Podría filtrar los caracteres ingresados ??en el campo cuando el texto se confirma utilizando el método UITextFieldDelegate:
- (BOOL)textFieldShouldReturn:(UITextField*)textField
Sin embargo, esto le da al usuario una falsa impresión, ya que aunque los caracteres restringidos se eliminan del valor final, aún se ingresaron visiblemente en el campo de texto antes de presionar Retorno / Listo / etc. ¿Cuál es el mejor enfoque que evitaría que aparezcan caracteres restringidos en el campo de texto cuando se seleccionan en el teclado?
Nota: estoy operando bajo el supuesto de que tengo poco control sobre qué teclas proporcionan los teclados del iPhone. Soy consciente de que puedo cambiar entre varias implementaciones de teclado, pero tengo la impresión de que no puedo desactivar teclas específicas. Esta suposición puede ser incorrecta.
Solución
Mira textField: shouldChangeCharactersInRange
Este UITextFieldDelegate
llama a este método cada vez que se escriben nuevos caracteres o se eliminan caracteres existentes del campo de texto. Puede devolver NO para no permitir el cambio.
Otros consejos
Hice lo que sugirió marcc y funcionó bien. A continuación se muestra un ejemplo de implementación.
Nota: los nombres de las variables se seleccionaron por brevedad y no reflejan mis estándares de codificación:
...
myCharSet = [NSCharacterSet characterSetWithCharactersInString:@"xyzXYZ"];
...
}
- (BOOL) textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)textEntered {
for (int i = 0; i < [textEntered length]; i++) {
unichar c = [textEntered characterAtIndex:i];
if (![myCharSet characterIsMember:c]) {
return NO;
}
}
return YES;
}
Este es uno de los enfoques más limpios para restringir los caracteres ingresados ??en un UITextField. Este enfoque permite el uso de múltiples NSCharacterSets predefinidos.
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
NSMutableCharacterSet *allowedCharacters = [NSMutableCharacterSet alphanumericCharacterSet];
[allowedCharacters formUnionWithCharacterSet:[NSCharacterSet whitespaceCharacterSet]];
[allowedCharacters formUnionWithCharacterSet:[NSCharacterSet symbolCharacterSet]];
if([string rangeOfCharacterFromSet:allowedCharacters.invertedSet].location == NSNotFound){
return YES;
}
return NO;
}
Observe el método UITextViewDelegate
- (BOOL) textField: (UITextField *) textField shouldChangeCharactersInRange: (NSRange) range replaceString: (NSString *) string
.
Es exactamente lo que necesitas.
Esto es lo que uso para restringir al usuario a mayúsculas. Ajuste la variable regex según el gusto:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString* regex = @"[^A-Z]";
return ([string rangeOfString: regex
options:NSRegularExpressionSearch].location == NSNotFound);
};
¿Qué tal esto?
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString* regex = @"[^a-z]";
return ([[string lowercaseString] rangeOfString: regex
options:NSRegularExpressionSearch].location == NSNotFound);
};
Nota:
Estoy haciendo todos los caracteres en minúsculas [string lowercaseString]
para que no necesite escribir en expresiones regulares para letras mayúsculas / minúsculas.
Puede realizar un bucle y seguir comprobando si la propiedad UITextField.text ha cambiado una vez que se llama al método DidBeginEditing. Si es así, verifique el texto y elimine los caracteres incorrectos.