仅允许UITextField输入的Numbers

时间:2012-10-17 23:09:51

标签: ios ipad cocoa-touch uitextfield uikeyboard

iPad没有像iPhone / iPod那样的“Numpad”键盘。

我正在寻找如何限制用户键盘只接受0到9的值。

我会想象使用UITextField的“shouldChangeCharactersInRange”,但我不知道实现它的最佳方法。

15 个答案:

答案 0 :(得分:70)

这就是我在SSN验证字段中处理问题的方法,如果需要,您可以修改最大长度并删除if语句检查键盘类型。

当用户键入而不是粘贴数据时,还有逻辑来抑制最大长度警报。

在此代码的上下文中,BasicAlert()是一个#define宏,只使用传递的标题和消息字符串显示UIAlertViewUIAlertController

// 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;
}

答案 1 :(得分:26)

您可以使用此代码仅允许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;
    }

答案 2 :(得分:18)

尝试此操作以避免文本字段清除问题

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
}

答案 3 :(得分:17)

Swift代码的非常具体的步骤

您可以通过实施func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool协议提供限制UITextFieldDelegate方法中文本字段输入的逻辑。

为了清楚起见,这些步骤假设您的故事板包含 视图控制器 ,并带有 文本字段 只应接受数字的对象。

  1. 为扩展UIViewController的视图控制器创建自定义类。 通过在Xcode的Identity Inspector中设置自定义类值,确保故事板中的场景引用自定义类。

    import UIKit
    class YourCustomController: UIViewController {
        override func viewDidLoad() {        
            super.viewDidLoad()
        }
    }
    
  2. 从场景的文本字段中创建一个插座到自定义视图控制器。

    class YourCustomController: UIViewController {
        @IBOutlet weak var numberField: UITextField!
        ...
    }
    
  3. 在自定义视图控制器中应用UITextFieldDelegate协议。

    class YourCustomController: UIViewController, UITextFieldDelegate {
        ...
    }
    
  4. 在自定义视图控制器的viewDidLoad方法中,将文本字段的委托指定给自定义视图控制器类。

    override func viewDidLoad() {        
        super.viewDidLoad()
        numberField.delegate = self
    }
    
  5. 添加UITextFieldDelegate的{​​{1}}方法。

    由于在上一步中将自定义视图控制器设置为func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool的委托,因此每次用户在文本字段中输入字符时都会调用此方法。如果您的方法返回numberField,则该字符将保留在文本字段中。如果您的方法返回true,那么的字符将保留在文本字段中。

    false参数是用户输入的字符。如果string字符可以转换为string,则它在0到9之间;否则,它是一些非数字字符。

    Int
  6. (有关完整视图控制器代码,请参见下文。)

    示例视图控制器,仅包含数字文本字段

    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

答案 4 :(得分:8)

- (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;
}

答案 5 :(得分:6)

我申请了这个并且有效!!

-(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;                                                                                                                                     
}

答案 6 :(得分:2)

NSString* val = [[textField text] stringByReplacingCharactersInRange:range withString:string];
    NSCharacterSet *allowedCharacterSet = [NSCharacterSet decimalDigitCharacterSet];
    if ([[string componentsSeparatedByCharactersInSet:[allowedCharacterSet invertedSet]] count] > 1 || [val length] > 5) {
        return NO;
    }

答案 7 :(得分:2)

makeRequest

答案 8 :(得分:1)

在Swift中:

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        return string.isEmpty || Int(string) != nil
    }

答案 9 :(得分:1)

迅速5

Padding(
              padding: const EdgeInsets.only(
                bottom:8.0,
                ),
)

您现在只能仅点击1234567890

答案 10 :(得分:0)

保持内部表示的不同演示数据。有一种更简单的方法。让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]]];

答案 11 :(得分:0)

我修改了@ 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; 
 }

答案 12 :(得分:0)

如果您使用我的specification 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
}

答案 13 :(得分:0)

swift 3

UIViewContentModeScaleToFill

答案 14 :(得分:-1)

使用此代码:

NSString* val = [[textField text] stringByReplacingCharactersInRange:range withString:string];
NSCharacterSet *allowedCharacterSet = [NSCharacterSet decimalDigitCharacterSet];
if ([[string componentsSeparatedByCharactersInSet:[allowedCharacterSet invertedSet]] count] > 1 || [val length] > 5) {
    return NO;
}