To restrict the possible input characters for a text view, implement the text view
delegate like this:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
static NSString *validChars = @"ABCDEFGHIJKLMNOPQRSTUVWYXZ1234567890\n";
NSCharacterSet *validSet = [NSCharacterSet characterSetWithCharactersInString:validChars];
if ([[text stringByTrimmingCharactersInSet:validSet] length] > 0)
return NO;
return YES;
}
\n
in validChars
is for the RETURN key (which you may or not may want to allow).
As suggested in the comments, you could convert lower case letters to upper case
automatically:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
text = [text uppercaseString];
static NSString *validChars = @"ABCDEFGHIJKLMNOPQRSTUVWYXZ1234567890\n";
NSCharacterSet *validSet = [NSCharacterSet characterSetWithCharactersInString:validChars];
if ([[text stringByTrimmingCharactersInSet:validSet] length] > 0)
return NO;
textView.text = [textView.text stringByReplacingCharactersInRange:range withString:text];
return NO;
}
To allow also uppercase letters and digits from other languages, change the
definition of validSet
to
NSMutableCharacterSet *validSet = [NSMutableCharacterSet uppercaseLetterCharacterSet];
[validSet formUnionWithCharacterSet:[NSCharacterSet decimalDigitCharacterSet]];
[validSet formUnionWithCharacterSet:[NSCharacterSet newlineCharacterSet]];
Since the text view delegate is called frequently, you can improve this by
using GCD to compute the set of valid characters only once:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
static NSCharacterSet *validSet;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSMutableCharacterSet *tmpSet = [NSMutableCharacterSet uppercaseLetterCharacterSet];
[tmpSet formUnionWithCharacterSet:[NSCharacterSet decimalDigitCharacterSet]];
[tmpSet formUnionWithCharacterSet:[NSCharacterSet newlineCharacterSet]];
validSet = [tmpSet copy];
});
text = [text uppercaseString];
if ([[text stringByTrimmingCharactersInSet:validSet] length] > 0)
return NO;
textView.text = [textView.text stringByReplacingCharactersInRange:range withString:text];
return NO;
}