ios - Permitir solo números para entrada de UITextField
ipad cocoa-touch (13)
¡Apliqué esto y funciona!
-(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;
}
El iPad no tiene un teclado "Numpad" como el iPhone / iPod.
Estoy buscando cómo restringir el teclado del usuario para que solo acepte los valores del 0 al 9.
Me imagino usando el "shouldChangeCharactersInRange" de UITextField pero no conozco la mejor manera de implementarlo.
He modificado la respuesta de @ iDev para trabajar con archivos digitales y ".":
-(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;
}
Intenta esto para evitar el problema de limpieza del campo de texto
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
}
Mantenga distintos datos de presentación de la representación interna. Hay una manera más simple. Deje NSNumberFormatter
hacer el trabajo:
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]]];
Puede usar este código para permitir solo el número en textField.
Antes de eso, delegue para textField
textFieldName.delegate=self;
o
[textFieldName setDelegate:self];
Que utilizar este código para permitir solo un dígito a campo de texto
- (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;
}
Si usa mi patrón de especificación, entonces el código se ve así:
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
}
Usa este código:
NSString* val = [[textField text] stringByReplacingCharactersInRange:range withString:string];
NSCharacterSet *allowedCharacterSet = [NSCharacterSet decimalDigitCharacterSet];
if ([[string componentsSeparatedByCharactersInSet:[allowedCharacterSet invertedSet]] count] > 1 || [val length] > 5) {
return NO;
}
veloz 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
}
Pasos muy específicos para el código Swift
Puede proporcionar una lógica que restrinja la entrada del campo de texto en el campo de texto de func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
Método func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
implementando el protocolo UITextFieldDelegate
.
En aras de la claridad, estos pasos suponen que su guión gráfico contiene un controlador de vista con un objeto de campo de texto que solo debe aceptar dígitos.
Cree una clase personalizada para el controlador de vista que extiende
UIViewController
. Asegúrese de que la escena en su guión gráfico se refiera a la clase personalizada estableciendo el valor de clase personalizado en el Inspector de identidad de Xcode.import UIKit class YourCustomController: UIViewController { override func viewDidLoad() { super.viewDidLoad() } }
Crea un punto de venta desde el campo de texto de tu escena hasta tu View Controller personalizado.
class YourCustomController: UIViewController { @IBOutlet weak var numberField: UITextField! ... }
Aplique el protocolo
UITextFieldDelegate
en su controlador de vista personalizado.class YourCustomController: UIViewController, UITextFieldDelegate { ... }
En el método
viewDidLoad
su controlador de vista personalizada, asigne el delegado de su campo de texto a su clase de controlador de vista personalizada.override func viewDidLoad() { super.viewDidLoad() numberField.delegate = self }
Agregue el campo de
UITextFieldDelegate
defunc textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
Métodofunc textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
.Como resultado de convertir su controlador de vista personalizado en el delegado de
numberField
en el paso anterior, se llamará a este método cada vez que un usuario ingrese un carácter en el campo de texto. Si su método devuelvetrue
, el personaje permanecerá en el campo de texto. Si su método devuelvefalse
, el personaje no permanecerá en el campo de texto.El parámetro de
string
es el carácter que ingresa el usuario. Si el carácter destring
se puede convertir a unInt
entonces está entre 0 y 9; de lo contrario, es un personaje no numérico.class YourCustomController: UIViewController, UITextFieldDelegate { ... func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { return Int(string) != nil } }
(Consulte a continuación el código del controlador de vista completa).
Controlador de vista de ejemplo con solo campo de texto de dígitos
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
}
}
Controlador de vista de ejemplo con un campo de texto decimal
Si desea admitir un número decimal, aproveche NSNumberFormatter
. Ver los comentarios del código para las diferencias.
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
}
}
Así es como manejé el problema en un campo de verificación del SSN, puede modificar la longitud máxima y eliminar la instrucción if
para buscar el tipo de teclado, si es necesario.
También hay lógica para suprimir las alertas de longitud máxima cuando el usuario está escribiendo en lugar de pegar datos.
En el contexto de este código, BasicAlert()
es una macro #define
que simplemente muestra un UIAlertView
o UIAlertController
utilizando las cadenas de título y mensaje pasadas.
// 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;
}
- (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;
}
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;
}