У iPad нет клавиатуры «Numpad», как у iPhone / iPod.
Я ищу, как я могу ограничить клавиатуру пользователя, чтобы принимать только значения от 0 до 9.
Я мог бы представить использование UITextField "shouldChangeCharactersInRange", но я не знаю, как лучше всего это реализовать.
ios
ipad
cocoa-touch
uitextfield
uikeyboard
Демастерпл
источник
источник
Ответы:
Вот как вы можете решить проблему с полем проверки SSN: вы можете изменить максимальную длину и удалить
if
проверку оператора для типа клавиатуры, если вам нужно.Существует также логика для подавления предупреждений о максимальной длине, когда пользователь вводит текст, в отличие от вставки данных.
В контексте этого кода
presentAlert()/presentAlert:
- это просто некоторая базовая функция, которая представляетUIAlertController
(или унаследованныйUIAlertView
), используя переданную строку сообщения.Swift 5
// 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. // // There are also some better stylistic approaches in Swift to avoid all the // nested statements, but I wanted to keep the styles similar to allow others // to contrast and compare between the two languages a little easier. func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { // Handle backspace/delete guard !string.isEmpty else { // Backspace detected, allow text change, no need to process the text any further return true } // Input Validation // Prevent invalid character input, if keyboard is numberpad if textField.keyboardType == .numberPad { // Check for invalid input characters if CharacterSet(charactersIn: "0123456789").isSuperset(of: CharacterSet(charactersIn: string)) { // Present alert so the user knows what went wrong presentAlert("This field accepts only numeric entries.") // Invalid characters detected, disallow text change return false } } // Length Processing // Need to convert the NSRange to a Swift-appropriate type if let text = textField.text, let range = Range(range, in: text) { let proposedText = text.replacingCharacters(in: range, with: string) // Check proposed text length does not exceed max character count guard proposedText.count <= maxCharacters else { // Present alert if pasting text // easy: pasted data has a length greater than 1; who copy/pastes one character? if string.count > 1 { // Pasting text, present alert so the user knows what went wrong presentAlert("Paste failed: Maximum character count exceeded.") } // Character count exceeded, disallow text change return false } // 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, etc) answerButton.isEnabled = (proposedText.count == 4) } // Allow text change return true }
Цель-C
// 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 { // Handle backspace/delete if (!string.length) { // Backspace detected, allow text change, no need to process the text any further return YES; } // Input Validation // Prevent invalid character input, if keyboard is numberpad if (textField.keyboardType == UIKeyboardTypeNumberPad) { if ([string rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet].invertedSet].location != NSNotFound) { [self presentAlert: @"This field accepts only numeric entries."]; return NO; } } // Length Validation NSString *proposedText = [textField.text stringByReplacingCharactersInRange:range withString:string]; // Check proposed text length does not exceed max character count if (proposedText.length > maxCharacters) { // Present alert if pasting text // easy: pasted data has a length greater than 1; who copy/pastes one character? if (string.length > 1) { // Pasting text, present alert so the user knows what went wrong [self presentAlert: @"Paste failed: Maximum character count exceeded."]; } // Character count exceeded, disallow text change 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, etc) self.answerButton.enabled = (proposedText.length == maxCharacters); // Allow text change return YES; }
источник
Вы можете использовать этот код, чтобы разрешить только число в textField.
Перед этим установите делегат для textField
textFieldName.delegate=self;
или же
[textFieldName setDelegate:self];
Затем используйте этот код, чтобы разрешить только цифру в textField
- (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; }
источник
[string intValue]
возвращает 0 для @ "0" - поэтомуif ([string intValue])
не выполняется для @ "0". Лучше использоватьif ([string rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]].location != NSNotFound)
@".".intValue
равно 0. И@"0".intValue
тоже 0.0
символ нуля ( ).Попробуйте это, чтобы избежать проблемы с очисткой текстового поля
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 }
источник
return guard CharacterSet(charactersIn: "0123456789").isSuperset(of: CharacterSet(charactersIn: string))
Очень конкретные шаги для кода Swift
Вы можете предоставить логику, ограничивающую ввод текстового поля в
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
методе, путем реализацииUITextFieldDelegate
протокола.Для ясности эти шаги предполагают, что ваша раскадровка содержит контроллер представления с объектом текстового поля, который должен принимать только цифры.
Создайте собственный класс для расширяемого контроллера представления
UIViewController
. Убедитесь, что сцена в вашей раскадровке относится к настраиваемому классу, установив значение настраиваемого класса в Identity Inspector Xcode.import UIKit class YourCustomController: UIViewController { override func viewDidLoad() { super.viewDidLoad() } }
Создайте выход из текстового поля сцены в пользовательский контроллер представления.
class YourCustomController: UIViewController { @IBOutlet weak var numberField: UITextField! ... }
Примените
UITextFieldDelegate
протокол в своем настраиваемом контроллере представления.class YourCustomController: UIViewController, UITextFieldDelegate { ... }
В
viewDidLoad
методе вашего настраиваемого контроллера представления назначьте делегата текстового поля вашему классу настраиваемого контроллера представления.override func viewDidLoad() { super.viewDidLoad() numberField.delegate = self }
Добавить в
UITextFieldDelegate
«Sfunc textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
метод.В результате того, что ваш пользовательский контроллер представления стал
numberField
делегатом на предыдущем шаге, этот метод будет вызываться каждый раз, когда пользователь вводит символ в текстовое поле. Если ваш метод вернется,true
то символ останется в текстовом поле. Если ваш метод вернется,false
то символ не останется в текстовом поле.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 } }
источник
return string.toInt() != nil
Работал как шарм. Благодаря!return Int(string) != nil
return string == "" || Int(string) != nil
- (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; }
источник
if (character < 48) return NO; // 48 unichar for 0 if (character > 57) return NO; // 57 unichar for 9
на.if ((character < 48 || character > 57) && character != 46)
Я бы дополнительно рекомендовал вам сравнитьcharacter
с шестнадцатеричным представлением чисел, поскольку шестнадцатеричные числа обычно используются в этих обстоятельствах. Т.е.if ((character < 0x30 || character > 0x39) && character != 0x2E)
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; }
источник
В Swift:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { return string.isEmpty || Int(string) != nil }
источник
быстрый 5
//MARK:- UITextFieldDelegate func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { let allowedCharacters = "1234567890" let allowedCharcterSet = CharacterSet(charactersIn: allowedCharacters) let typedCharcterSet = CharacterSet(charactersIn: string) return allowedCharcterSet.isSuperset(of: typedCharcterSet) }
Теперь вы можете просто нажать только 1234567890
источник
Храните отдельные данные презентации от внутреннего представления. Есть способ попроще. Позвольте
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]]];
источник
Если вы используете мой шаблон спецификации, то код будет выглядеть так
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, чтобы он работал с цифровыми изображениями и ".":
-(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; }
источник
быстрый 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; }
источник