2011-09-24 27 views

Respuesta

57

Utilice el método UITextFieldDelegate -textField:shouldChangeCharactersInRange:replacementString: con un NSCharacterSet que contiene el inverso de los caracteres que desea permitir. Por ejemplo:

// in -init, -initWithNibName:bundle:, or similar 
NSCharacterSet *blockedCharacters = [[[NSCharacterSet alphanumericCharacterSet] invertedSet] retain]; 

- (BOOL)textField:(UITextField *)field shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)characters 
{ 
    return ([characters rangeOfCharacterFromSet:blockedCharacters].location == NSNotFound); 
} 

// in -dealloc 
[blockedCharacters release]; 

Tenga en cuenta que tendrá que declarar que su clase implementa el protocolo (es decir @interface MyClass : SomeSuperclass <UITextFieldDelegate>) y ajuste de delegate a la instancia de la clase del campo de texto.

+0

Quiere decir: return [characters rangeOfCharacterFromSet: blockedCharacters] .location == NSNotFound; – Sagiftw

+0

Tienes razón, yo sí. Gracias por la corrección. –

+0

¿Alguna razón particular por la que invirtió el conjunto de caracteres alfanuméricos? ¿No podría eliminar el conjunto invertido y luego cambiar su prueba de retorno a! = NSNotFound? Es curioso ya que tengo algo de lógica sucediendo allí además del retorno – nbsp

11

Esto es cómo lo hago:

// Define some constants: 
#define ALPHA     @"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 
#define NUMERIC     @"1234567890" 
#define ALPHA_NUMERIC   ALPHA NUMERIC 

// Make sure you are the text fields 'delegate', then this will get called before text gets changed. 
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { 

    // This will be the character set of characters I do not want in my text field. Then if the replacement string contains any of the characters, return NO so that the text does not change. 
    NSCharacterSet *unacceptedInput = nil; 

    // I have 4 types of textFields in my view, each one needs to deny a specific set of characters: 
    if (textField == emailField) { 
     // Validating an email address doesnt work 100% yet, but I am working on it.... The rest work great! 
     if ([[textField.text componentsSeparatedByString:@"@"] count] > 1) { 
      unacceptedInput = [[NSCharacterSet characterSetWithCharactersInString:[ALPHA_NUMERIC stringByAppendingString:@".-"]] invertedSet]; 
     } else { 
      unacceptedInput = [[NSCharacterSet characterSetWithCharactersInString:[ALPHA_NUMERIC stringByAppendingString:@".!#$%&'*+-/=?^_`{|}[email protected]"]] invertedSet]; 
     } 
    } else if (textField == phoneField) { 
     unacceptedInput = [[NSCharacterSet characterSetWithCharactersInString:NUMERIC] invertedSet]; 
    } else if (textField == fNameField || textField == lNameField) { 
     unacceptedInput = [[NSCharacterSet characterSetWithCharactersInString:ALPHA] invertedSet]; 
    } else { 
     unacceptedInput = [[NSCharacterSet illegalCharacterSet] invertedSet]; 
    } 

    // If there are any characters that I do not want in the text field, return NO. 
    return ([[string componentsSeparatedByCharactersInSet:unacceptedInput] count] <= 1); 
} 

Mira la UITextFieldDelegate Reference también.

+0

que es realmente útil. Lo único que agregué fue 'if (([string isEqualToString: @" @ "]) && (range.location == 0)) {unacceptedInput = [NSCharacterSet characterSetWithCharactersInString: @" @ "]; } ' dentro de la rama emailField para evitar que @ se use para iniciar una dirección de correo electrónico – Ryan

0

Usted tendrá que utilizar los métodos textField delegate, y métodos de uso textFieldDidBeginEditing, shouldChangeCharactersInRange y textFieldDidEndEditing para comprobar los caracteres.

Por favor, consulte this link para la documentación.

11

encontré una respuesta simple y trabajando y quieren compartir:

conectar su UITextField para el evento EditingChanged al siguiente IBAction

-(IBAction) editingChanged:(UITextField*)sender 
{  
    if (sender == yourTextField) 
    { 
     // allow only alphanumeric chars 
     NSString* newStr = [sender.text stringByTrimmingCharactersInSet:[[NSCharacterSet alphanumericCharacterSet] invertedSet]]; 

     if ([newStr length] < [sender.text length]) 
     { 
      sender.text = newStr; 
     } 
    } 
} 
+0

+1 para creatividad – ArtOfWarfare

+0

Una pregunta: ¿comparar longitudes es mejor que simplemente comparar contenidos?A menos que la longitud se almacene realmente en el objeto NSString, me imagino que la comparación tomaría 'm + n' time, donde' m' es la longitud de 'newStr' y' n' es la longitud de 'sender.text '. – ArtOfWarfare

1

para SWIFT: Conecte su UITextField para el evento EditingChanged al siguiente IBAction:

@IBAction func ActionChangeTextPassport(sender:UITextField){ 
    if sender == txtPassportNum{ 
     let newStr = sender.text?.stringByTrimmingCharactersInSet(NSCharacterSet.alphanumericCharacterSet().invertedSet) 
     if newStr?.characters.count < sender.text?.characters.count{ 
      sender.text = newStr 
     } 
    } 
} 
4

Swift 3 versión

enfoque respuesta Actualmente aceptado:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { 

    // Get invalid characters 
    let invalidChars = NSCharacterSet.alphanumerics.inverted 

    // Attempt to find the range of invalid characters in the input string. This returns an optional. 
    let range = string.rangeOfCharacter(from: invalidChars) 

    if range != nil { 
     // We have found an invalid character, don't allow the change 
     return false 
    } else { 
     // No invalid character, allow the change 
     return true 
    } 
} 

Otro enfoque igualmente funcionales:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { 

    // Get invalid characters 
    let invalidChars = NSCharacterSet.alphanumerics.inverted 

    // Make new string with invalid characters trimmed 
    let newString = string.trimmingCharacters(in: invalidChars) 

    if newString.characters.count < string.characters.count { 
     // If there are less characters than we started with after trimming 
     // this means there was an invalid character in the input. 
     // Don't let the change go through 
     return false 
    } else { 
     // Otherwise let the change go through 
     return true 
    } 

} 
+0

Esto no funciona si el usuario pega en caracteres no deseados – MarksCode

+0

@MarksCode estás en lo correcto. Actualicé ese enfoque para trabajar con los personajes pegados. También agregué el mismo enfoque que usa la respuesta aceptada. – teradyl

1

La forma RegEx en Swift:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { 
    if string.isEmpty { 
     return true 
    } 
    let alphaNumericRegEx = "[a-zA-Z0-9]" 
    let predicate = NSPredicate(format:"SELF MATCHES %@", alphaNumericRegEx) 
    return predicate.evaluate(with: string) 
} 
Cuestiones relacionadas