I have UITexfields i want that it should accept only number other shows alert that enter a numeric value. I want that motionSicknessTextFiled should only accept number
Here is the working example for swift 4
public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
{
// Allow Backspace
if string.count == 0 {
return true
}
// Allow Only Valid Decimal Numbers
if let textFieldText = textField.text {
let finalText = (textFieldText as NSString).replacingCharacters(in: range, with: string)
if Double(finalText) != nil {
return true
}
}
return false
}
Swift
class ExampleVC: UIViewController {
let numbers = "0123456789";
override func viewDidLoad() {
super.viewDidLoad()
let textfield = UITextField(frame: CGRectMake(20, 100, 300, 44))
//make some customization, if you want
self.view.addSubview(textfield)
textfield.delegate = self;
}
}
extension ExampleVC: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
return string.characters.count > 0 ? numbers.contains(string) : true
}
}
This answer threw some error in Swift 3, here's the working answer:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if string.characters.count == 0 {
return true
}
do {
if textField == self.numberTextField {
let nString = textField.text as NSString?
let newString = nString?.replacingCharacters(in: range, with: string)
let expression = "^([0-9]+)?(\\.([0-9]{1,2})?)?$"
let regex = try NSRegularExpression(pattern: expression, options: .caseInsensitive)
let numberOfMatches = regex.numberOfMatches(in: newString! as String, options: [], range: NSRange(location: 0, length: (newString?.characters.count)!))
if numberOfMatches == 0 {
return false
}
}
}
catch let error {
}
return true
}
In whatever UITextField you're getting these values from, you can specify the kind of keyboard you want to appear when somebody touches inside the text field.
E.G. a numeric-only keyboard.
Like this screenshot:
This is easily set when working with the XIB and the Interface Builder built into Xcode, but if you want to understand this programmatically, take a look at Apple's UITextInputTraits protocol reference page, specifically the keyboardType property information.
To filter out punctuations, set the textfield's delegate and set up the shouldChangeCharactersInRange method:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSCharacterSet *numbersOnly = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
NSCharacterSet *characterSetFromTextField = [NSCharacterSet characterSetWithCharactersInString:textField.text];
BOOL stringIsValid = [numbersOnly isSupersetOfSet:characterSetFromTextField];
return stringIsValid;
}
The code is the UITextField
delegate method. Before you use this snippet, you must have these properties:
self.maxCharacters
self.numeric
// Only int characters.self.decimalNumeric
// Only numbers and ".", "," (for specific locales, like Russian).- (BOOL)textField:(UITextField *) textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if(self.numeric || self.decimalNumeric)
{
NSString *fulltext = [textField.text stringByAppendingString:string];
NSString *charactersSetString = @"0123456789";
// For decimal keyboard, allow "dot" and "comma" characters.
if(self.decimalNumeric) {
charactersSetString = [charactersSetString stringByAppendingString:@".,"];
}
NSCharacterSet *numbersOnly = [NSCharacterSet characterSetWithCharactersInString:charactersSetString];
NSCharacterSet *characterSetFromTextField = [NSCharacterSet characterSetWithCharactersInString:fulltext];
// If typed character is out of Set, ignore it.
BOOL stringIsValid = [numbersOnly isSupersetOfSet:characterSetFromTextField];
if(!stringIsValid) {
return NO;
}
if(self.decimalNumeric)
{
NSString *currentText = [textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
// Change the "," (appears in other locale keyboards, such as russian) key ot "."
currentText = [currentText stringByReplacingOccurrencesOfString:@"," withString:@"."];
// Check the statements of decimal value.
if([fulltext isEqualToString:@"."]) {
textField.text = @"0.";
return NO;
}
if([fulltext rangeOfString:@".."].location != NSNotFound) {
textField.text = [fulltext stringByReplacingOccurrencesOfString:@".." withString:@"."];
return NO;
}
// If second dot is typed, ignore it.
NSArray *dots = [fulltext componentsSeparatedByString:@"."];
if(dots.count > 2) {
textField.text = currentText;
return NO;
}
// If first character is zero and second character is > 0, replace first with second. 05 => 5;
if(fulltext.length == 2) {
if([[fulltext substringToIndex:1] isEqualToString:@"0"] && ![fulltext isEqualToString:@"0."]) {
textField.text = [fulltext substringWithRange:NSMakeRange(1, 1)];
return NO;
}
}
}
}
// Check the max characters typed.
NSUInteger oldLength = [textField.text length];
NSUInteger replacementLength = [string length];
NSUInteger rangeLength = range.length;
NSUInteger newLength = oldLength - rangeLength + replacementLength;
BOOL returnKey = [string rangeOfString: @"\n"].location != NSNotFound;
return newLength <= _maxCharacters || returnKey;
}
Modified Michael Dautermann's answer:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if(string.length > 0)
{
NSCharacterSet *numbersOnly = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
NSCharacterSet *characterSetFromTextField = [NSCharacterSet characterSetWithCharactersInString:string];
BOOL stringIsValid = [numbersOnly isSupersetOfSet:characterSetFromTextField];
return stringIsValid;
}
return YES;
}