Разрешить только числа для ввода UITextField
у iPad нет клавиатуры "Numpad", как у iPhone/iPod.
Я ищу, как я могу ограничить клавиатуру пользователя, чтобы принимать только значения от 0 до 9.
Я бы предположил использование UITextField "shouldChangeCharactersInRange", но я не знаю лучшего способа его реализации.
13 ответов:
вот как я справился с проблемой в поле проверки SSN, вы можете изменить максимальную длину и удалить
ifпроверка оператора для типа клавиатуры, если вам нужно.существует также логика подавления предупреждений о максимальной длине, когда пользователь вводит, а не вставляет данные.
в контексте этого кода
BasicAlert()это#defineмакрос, который просто показываетUIAlertViewилиUIAlertControllerиспользование переданных строк заголовка и сообщения.// NOTE: This code assumes you have set the UITextField(s)'s delegate property to the object that will contain this code, because otherwise it would never be called. - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { // allow backspace if (!string.length) { return YES; } // Prevent invalid character input, if keyboard is numberpad if (textField.keyboardType == UIKeyboardTypeNumberPad) { if ([string rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet].invertedSet].location != NSNotFound) { // BasicAlert(@"", @"This field accepts only numeric entries."); return NO; } } // verify max length has not been exceeded NSString *proposedText = [textField.text stringByReplacingCharactersInRange:range withString:string]; if (proposedText.length > 4) // 4 was chosen for SSN verification { // suppress the max length message only when the user is typing // easy: pasted data has a length greater than 1; who copy/pastes one character? if (string.length > 1) { // BasicAlert(@"", @"This field accepts a maximum of 4 characters."); } return NO; } // only enable the OK/submit button if they have entered all numbers for the last four of their SSN (prevents early submissions/trips to authentication server) self.answerButton.enabled = (proposedText.length == 4); return YES; }
вы можете использовать этот код, чтобы разрешить только номер в текстовом поле.
перед этим установите делегат для textField
textFieldName.delegate=self;или
[textFieldName setDelegate:self];чем использовать этот код, чтобы разрешить только цифры в поле
- (BOOL) textField: (UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString: (NSString *)string { //return yes or no after comparing the characters // allow backspace if (!string.length) { return YES; } ////for Decimal value start//////This code use use for allowing single decimal value // if ([theTextField.text rangeOfString:@"."].location == NSNotFound) // { // if ([string isEqualToString:@"."]) { // return YES; // } // } // else // { // if ([[theTextField.text substringFromIndex:[theTextField.text rangeOfString:@"."].location] length]>2) // this allow 2 digit after decimal // { // return NO; // } // } ////for Decimal value End//////This code use use for allowing single decimal value // allow digit 0 to 9 if ([string intValue]) { return YES; } return NO; }
очень конкретные шаги для Swift-кода
вы можете предоставить логику, которая ограничивает ввод текстового поля в
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Boolспособ реализацииUITextFieldDelegateпротокол.для ясности, эти шаги предполагают, что раскадровка содержит Посмотреть Контроллер С текстовое поле объект, который должен принимать только цифры.
создать пользовательский класс для контроллера вида, который расширяет
UIViewController. убедится что сцена в раскадровке ссылается на пользовательский класс, задавая значение пользовательского класса в Инспекторе идентификации Xcode.import UIKit class YourCustomController: UIViewController { override func viewDidLoad() { super.viewDidLoad() } }создайте выход из текстового поля сцены в пользовательский контроллер вида.
class YourCustomController: UIViewController { @IBOutlet weak var numberField: UITextField! ... }применить
UITextFieldDelegateпротокол в пользовательский контроллер представления.class YourCustomController: UIViewController, UITextFieldDelegate { ... }In ваш пользовательский контроллер представления
viewDidLoadметод, назначьте делегат вашего текстового поля для вашего пользовательского класса контроллера вида.override func viewDidLoad() { super.viewDidLoad() numberField.delegate = self }добавить
UITextFieldDelegate' sfunc textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Boolметод.в результате создания пользовательского контроллера вида
numberFieldс делегатом на предыдущем шаге, этот метод будет вызываться каждый раз, когда пользователь вводит символ в текстовое поле. Если ваш метод возвращаетtrueтогда символ останется в текстовом поле. Если ваш метод возвращаетfalseтогда персонаж будет не остается в текстовом поле.The
stringпараметр-это символ, введенный пользователем. Еслиstringперсонаж может быть преобразован вIntтогда это между 0 и 9; в противном случае, это какой-то не числовой символ.class YourCustomController: UIViewController, UITextFieldDelegate { ... func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { return Int(string) != nil } }(см. ниже полный код контроллера вида.)
пример контроллера вида с цифрами только текст поле
import UIKit class YourCustomController: UIViewController, UITextFieldDelegate { @IBOutlet weak var numberField: UITextField! override func viewDidLoad() { super.viewDidLoad() numberField.delegate = self } func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { return Int(string) != nil } }
пример контроллера вида с десятичным текстовым полем
если вы хотите поддерживать десятичное число, то воспользуйтесь
NSNumberFormatter. См. комментарии кода для различий.import UIKit class YourCustomController: UIViewController, UITextFieldDelegate { @IBOutlet weak var numberField: UITextField! private var formatter: NSNumberFormatter! override func viewDidLoad() { super.viewDidLoad() numberField.delegate = self // Initialize the formatter; minimum value is set to zero; style is Decimal. formatter = NSNumberFormatter() formatter.numberStyle = NSNumberFormatterStyle.DecimalStyle formatter.minimum = 0 } func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { // Combine the current text field value and the new string // character. If it conforms to the formatter's settings then // it is valid. If it doesn't then nil is returned and the // string character should not be allowed in the text field. return formatter.numberFromString("\(textField.text)\(string)") != nil } }
попробуйте это, чтобы избежать проблемы очистки текстового поля
Swift 3.0
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { guard NSCharacterSet(charactersInString: "0123456789").isSupersetOfSet(NSCharacterSet(charactersInString: string)) else { return false } return true }Swift 4.0
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { guard CharacterSet(charactersIn: "0123456789").isSuperset(of: CharacterSet(charactersIn: string)) else { return false } return true }
- (BOOL) textField: (UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString: (NSString *)string { NSNumberFormatter * nf = [[NSNumberFormatter alloc] init]; [nf setNumberStyle:NSNumberFormatterNoStyle]; NSString * newString = [NSString stringWithFormat:@"%@%@",textField.text,string]; NSNumber * number = [nf numberFromString:newString]; if (number) return YES; else return NO; }
я применил это, и это работает!!
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{ // Check for non-numeric characters NSUInteger lengthOfString = string.length; for (NSInteger index = 0; index < lengthOfString; index++) { unichar character = [string characterAtIndex:index]; if (character < 48) return NO; // 48 unichar for 0 if (character > 57) return NO; // 57 unichar for 9 } // Check total length for restrict user NSUInteger proposedNewLength = textField.text.length - range.length + string.length; if (proposedNewLength > 6) return YES; return YES; }
NSString* val = [[textField text] stringByReplacingCharactersInRange:range withString:string]; NSCharacterSet *allowedCharacterSet = [NSCharacterSet decimalDigitCharacterSet]; if ([[string componentsSeparatedByCharactersInSet:[allowedCharacterSet invertedSet]] count] > 1 || [val length] > 5) { return NO; }
Works fine for me : - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { if (([string rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]].location != NSNotFound) && !(range.length==1 && string.length==0)) { return NO; } return YES; }
держите различные данные представления от внутреннего представления. Есть более простой способ. Пусть
NSNumberFormatterвыполнить задание:NSNumberFormatter* ns = [[NSNumberFormatter alloc] init]; ns.numberStyle = NSNumberFormatterDecimalStyle; [ns setMaximumFractionDigits:2]; // This is your internal representation of the localized number double a = [[ns numberFromString:self.textIVA.text] doubleValue]]; [mylabel setText:[NSString stringWithFormat:@"€ %@", [NSNumberFormatter localizedStringFromNumber: [NSNumber numberWithDouble:a] numberStyle:NSNumberFormatterDecimalStyle]]];
Если вы используете мои спецификация pattern тогда код выглядит так
textField.delegate = self lazy var specification: Specification = { return RegularExpressionSpecification(pattern: "^(|0|[1-9]\d{0,6})$") }() func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { let textFieldString: NSString = textField.text ?? "" let s = textFieldString.stringByReplacingCharactersInRange(range, withString:string) return specification.isSatisfiedBy(s) } func textFieldShouldReturn(textField: UITextField) -> Bool { let s = textField.text ?? "" let isTextValid = specification.isSatisfiedBy(s) if isTextValid { textField.resignFirstResponder() } return false }
Я изменил ответ @iDev, чтобы работать для digitals и ".":
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{ // Check for non-numeric characters NSUInteger lengthOfString = string.length; for (NSInteger index = 0; index < lengthOfString; index++) { unichar character = [string characterAtIndex:index]; if ((character < 48) && (character != 46)) return NO; // 48 unichar for 0, and 46 unichar for point if (character > 57) return NO; // 57 unichar for 9 } // Check for total length NSUInteger proposedNewLength = textField.text.length - range.length + string.length; if (proposedNewLength > 6) return YES; return YES; }
swift 3
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if textField==yourTextFieldOutlet { if(CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: yourTextFieldOutlet.text!))){ //if numbers only, then your code here } else{ showAlert(title: "Error",message: "Enter Number only",type: "failure") } } return true }
используйте этот код:
NSString* val = [[textField text] stringByReplacingCharactersInRange:range withString:string]; NSCharacterSet *allowedCharacterSet = [NSCharacterSet decimalDigitCharacterSet]; if ([[string componentsSeparatedByCharactersInSet:[allowedCharacterSet invertedSet]] count] > 1 || [val length] > 5) { return NO; }
Comments