2011-09-24 8 views

risposta

57

Utilizzare il metodo UITextFieldDelegate -textField:shouldChangeCharactersInRange:replacementString: con un NSCharacterSet contenente l'inverso dei caratteri che si desidera consentire. Per esempio:

// 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]; 

Nota che avrete bisogno di dichiarare che la classe implementa il protocollo (cioè @interface MyClass : SomeSuperclass <UITextFieldDelegate>) e impostare il delegate all'istanza della classe campo di testo.

+0

Intendi: return [caratteri rangeOfCharacterFromSet: blockedCharacters] .location == NSNotFound; – Sagiftw

+0

Hai ragione, lo so. Grazie per la correzione. –

+0

Un motivo particolare per cui è stato invertito il set di caratteri alfanumerici? Non è possibile rimuovere l'invertedSet e quindi modificare il test di ritorno su! = NSNotFound? Solo curioso visto che ho avuto qualche logica in là, oltre al ritorno – nbsp

11

Questo è come lo faccio:

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

Scopri i UITextFieldDelegate Reference troppo.

+0

Questo è veramente utile. L'unica cosa che ho aggiunto è stata 'if (([string isEqualToString: @" @ "]) && (range.location == 0)) {unacceptedInput = [NSCharacterSet characterSetWithCharactersInString: @" @ "]; } all'interno del ramo Campo email per impedire a @ di essere utilizzato per avviare un indirizzo email – Ryan

0

Si dovrà utilizzare i textField delegate metodi e utilizzare metodi textFieldDidBeginEditing, shouldChangeCharactersInRange e textFieldDidEndEditing per controllare i personaggi.

Fare riferimento a this link per la documentazione.

11

ho trovato una risposta semplice e di lavoro e voglio condividere:

collegare l'UITextField per l'evento EditingChanged al seguente 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 per la creatività – ArtOfWarfare

+0

Una domanda: il confronto delle lunghezze è migliore del semplice confronto dei contenuti?A meno che la lunghezza non sia effettivamente memorizzata nell'oggetto NSString, immagino in entrambi i casi che il confronto prenda 'm + n' time, dove' m' è la lunghezza di 'newStr' e' n' è la lunghezza di 'sender.text '. – ArtOfWarfare

1

per SWIFT: Collegare l'UITextField per l'evento EditingChanged a seguire 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 versione

Attualmente accettato approccio risposta:

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

Un altro approccio altrettanto funzionale:

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

Questo non funziona se l'utente incolla in caratteri indesiderati – MarksCode

+0

@MarksCode sei corretto. Ho aggiornato questo approccio per lavorare con i caratteri incollati. Ho anche aggiunto lo stesso approccio utilizzato dalla risposta accettata. – teradyl

1

Il modo RegEx a 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) 
} 
Problemi correlati