In my application i need to allow users input only numbe开发者_高级运维rs. How can i allow UITextField to receive only numbers from user?
The characters in this examples are allowed, so if you dont want the user to use a character, exclude it from myCharSet
.
- (BOOL)textField:(UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSCharacterSet *myCharSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
for (int i = 0; i < [string length]; i++) {
unichar c = [string characterAtIndex:i];
if (![myCharSet characterIsMember:c]) {
return NO;
}
}
return YES;
}
I prefer the following solution that actually prevents any any input except from numbers and backspace. Backspace for some reason is represented by an empty string and could not be used unless empty string returns YES. I also popup an alert view when the user enters a character other that numbers.
- (BOOL)textField:(UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (string.length == 0) {
return YES;
}
NSCharacterSet *myCharSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
for (int i = 0; i < [string length]; i++) {
unichar c = [string characterAtIndex:i];
if ([myCharSet characterIsMember:c]) {
return YES;
}
}
UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Invalid Input" message:@"Only numbers are allowed for participant number." delegate:self cancelButtonTitle:@"Dismiss" otherButtonTitles:nil];
[av show];
return NO;
}
This is perhaps the cleanest, simplest solution to allow only positive or negative numbers. This also allows backspace.
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
NSCharacterSet *allowedCharacters = [NSCharacterSet characterSetWithCharactersInString:@"-0123456789"];
if([string rangeOfCharacterFromSet:allowedCharacters.invertedSet].location == NSNotFound){
return YES;
}
return NO;
}
One thing you can do is to show the numbers key pad and beside text field or some where else add a dynamic button to hide the keyboard.
you guys might flame.. but this worked for me.. only numbers (including negatives), and backspace.
NSCharacterSet *validCharSet;
if (range.location == 0)
validCharSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789-."];
else
validCharSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789."];
if ([[string stringByTrimmingCharactersInSet:validCharSet] length] > 0 ) return NO; //not allowable char
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber* candidateNumber;
NSString* candidateString = [textField.text stringByReplacingCharactersInRange:range withString:string];
range = NSMakeRange(0, [candidateString length]);
[numberFormatter getObjectValue:&candidateNumber forString:candidateString range:&range error:nil];
if (candidateNumber == nil ) {
if (candidateString.length <= 1)
return YES;
else
return NO;
}
return YES;
Here is my solution applying algebra of sets with the method isSupersetOfSet:
This also doesn't allow pasting text with invalid characters:
- (BOOL)textField:(UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (string.length == 0 || [_numericCharSet isSupersetOfSet:[NSCharacterSet characterSetWithCharactersInString:string]]) {
return YES;
}
else {
UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Invalid Input"
message:@"Only numeric input allowed."
delegate:self
cancelButtonTitle:@"Close"
otherButtonTitles:nil];
[av show];
return NO;
}
}
Note: according to Apple Developer Library, It's preferable cache the static NSCharacterSet
than to create it again and again (here _numericCharSet
).
However I prefer to let the user to input any character and validate the value in the method textFieldShouldEndEditing:
called when the textField tries to resign first responder.
In this manner the user can paste any text (maybe composed with a mix of letters and numbers) and tidy up it in my textFields. The users do not like to see limited their actions.
In Swift
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if textField.tag == 2 { //your textField
let invalid = NSCharacterSet(charactersInString: "aeiou") //characters to block
if let range = string.rangeOfCharacterFromSet(invalid) {
return false
}
}
return true
}
Here is a swift example
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
var disabledCharacters:NSCharacterSet = NSCharacterSet(charactersInString: "0123456789")
for (var i:Int = 0; i < count(string); ++i) {
var c = (string as NSString).characterAtIndex(i)
if (disabledCharacters.characterIsMember(c)) {
println("Can't use that character dude :/")
return false
}
}
return true
}
Don't forget to add UITextFieldDelegate
to your UIViewController
as well.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
char *x = (char*)[string UTF8String];
//NSLog(@"char index is %i",x[0]);
if([string isEqualToString:@"-"] || [string isEqualToString:@"("] || [string isEqualToString:@")"] || [string isEqualToString:@"0"] || [string isEqualToString:@"1"] || [string isEqualToString:@"2"] || [string isEqualToString:@"3"] || [string isEqualToString:@"4"] || [string isEqualToString:@"5"] || [string isEqualToString:@"6"] || [string isEqualToString:@"7"] || [string isEqualToString:@"8"] || [string isEqualToString:@"9"] || x[0]==0 || [string isEqualToString:@" "]) {
NSUInteger newLength = [textField.text length] + [string length] - range.length;
return (newLength > 14) ? NO : YES;
} else {
return NO;
}
}
This thread is a little old, but for the sake of reference I am going to leave a solution in swift 3. This solution will combine decimalDigits
and the actual decimal. You can put together whatever combination you'd like, but for my case this is what the requirements were.
// instantiate a mutable character set
let characterSet = NSMutableCharacterSet()
// assign the needed character set
characterSet.formUnion(with: NSCharacterSet.decimalDigits)
// only need the decimal character added to the character set
characterSet.addCharacters(in: ".")
// invert and return false if it's anything other than what we're looking for
if string.rangeOfCharacter(from: characterSet.inverted) != nil {
return false
}
精彩评论