2011-09-24 120 views

回答

57

使用UITextFieldDelegate方法-textField:shouldChangeCharactersInRange:replacementString:與包含要允許字符的倒數的NSCharacterSet。例如:

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

請注意,您必須聲明你的類實現的協議(即@interface MyClass : SomeSuperclass <UITextFieldDelegate>),並設置文本字段的delegate你的類的實例。

+0

你的意思是:返回[人物rangeOfCharacterFromSet:blockedCharacters] .location == NSNotFound; – Sagiftw

+0

你說得對,我喜歡。感謝您的更正。 –

+0

您反轉字母數字字符集的任何特定原因?難道你不能刪除invertedSet,然後將你的返回測試改爲!= NSNotFound?只是好奇,我有一些邏輯發生在那裏除了剛剛返回 – nbsp

11

這是我要做的事:

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

退房的UITextFieldDelegate Reference了。

+0

這真的很有幫助。我只加入件事是 '如果((字符串isEqualToString:@ 「@」])&&(range.location == 0)){unacceptedInput = [NSCharacterSet characterSetWithCharactersInString:@ 「@」]; }' 的emailField分支,以防止@被用來啓動一個電子郵件地址內 – Ryan

0

您將不得不使用textField delegate方法,並使用方法textFieldDidBeginEditing,shouldChangeCharactersInRangetextFieldDidEndEditing來檢查字符。

請參考this link的文檔。

11

我發現了一個簡單的工作的答案,並希望分享:

連接你的UITextField的事件EditingChanged到以下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創意 – ArtOfWarfare

+0

一個問題 - 在比較長的任何不僅僅是內容比較好?除非長度實際上存儲在NSString對象中,否則我會想象比較會花費時間'm + n',其中'm'是'newStr'的長度,'n'是'sender.text的長度'。 – ArtOfWarfare

1

對於斯威夫特: 連接您的UITextField的事件EditingChanged到以下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

斯威夫特3版

目前接受的回答方式:

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

另一個同樣功能的方法:

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

這不工作,如果用戶粘貼在不需要的字符 – MarksCode

+0

@MarksCode你是正確的。我更新了這種方法來處理粘貼的字符。我還添加了接受的答案使用的相同方法。 – teradyl

1

正則表達式的方式斯威夫特:

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