仅允许UITextField输入的Numbers

Dem*_*rpl 78 cocoa-touch uitextfield uikeyboard ipad ios

iPad没有像iPhone/iPod那样的"Numpad"键盘.

我想找到如何限制用户的键盘只接受值0到9.

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

Thu*_*ets 75

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

当用户键入而不是粘贴数据时,还存在抑制最大长度警报的逻辑.

在此代码的上下文中,presentAlert()/presentAlert:是一个UIAlertController宏,它只显示UIAlertViewif使用传递的标题和消息字符串.

// 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
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!“如果键盘是数字键盘,则从输入中删除无效字符”部分有助于回答我的问题! (2认同)

小智 26

您可以使用此代码仅允许textField中的数字.

在为textField设置委托之前

      textFieldName.delegate=self;
Run Code Online (Sandbox Code Playgroud)

要么

      [textFieldName setDelegate:self];
Run Code Online (Sandbox Code Playgroud)

比使用此代码只允许数字到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;
    }
Run Code Online (Sandbox Code Playgroud)

  • 顺便说一句,对于使用这段代码的其他人来说,`[string intValue]`为@"0"返回0 - 所以`@([string intValue])`不符合@"0".最好使用`if([string rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]].location!= NSNotFound)` (4认同)
  • `@".".intValue`是0.而且`@"0".intValue`也是0. (2认同)

SPa*_*tel 21

试试这个以避免文本字段清除问题

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
}
Run Code Online (Sandbox Code Playgroud)

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
}
Run Code Online (Sandbox Code Playgroud)

  • 您可以简化委托方法,并只剩下“返回保护CharacterSet(charactersIn:“ 0123456789”)。isSuperset(of:CharacterSet(charactersIn:string))` (2认同)

why*_*ite 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()
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 从场景的文本字段创建一个插座到自定义视图控制器.

    class YourCustomController: UIViewController {
        @IBOutlet weak var numberField: UITextField!
        ...
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. UITextFieldDelegate在自定义视图控制器中应用协议.

    class YourCustomController: UIViewController, UITextFieldDelegate {
        ...
    }
    
    Run Code Online (Sandbox Code Playgroud)
  4. 在自定义视图控制器的viewDidLoad方法中,将文本字段的委托分配给自定义视图控制器类.

    override func viewDidLoad() {        
        super.viewDidLoad()
        numberField.delegate = self
    }
    
    Run Code Online (Sandbox Code Playgroud)
  5. 添加UITextFieldDelegatefunc textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool方法.

    由于numberField在上一步中将自定义视图控制器设置为委托,因此每次用户在文本字段中输入字符时都会调用此方法.如果您的方法返回,true则该字符将保留在文本字段中.如果您的方法返回,false则该字符将不会保留在文本字段中.

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

    class YourCustomController: UIViewController, UITextFieldDelegate {
        ...
        func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    
            return Int(string) != nil
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

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


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

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
    }    
}
Run Code Online (Sandbox Code Playgroud)

带有十进制文本字段的示例视图控制器

如果您想支持十进制数,那么请利用 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
    }    
}
Run Code Online (Sandbox Code Playgroud)

  • 我必须做的另一个改变 - 删除键不再有用!所以我把它改成了`return string ==""|| Int(string)!= nil` (7认同)
  • 这很好,但做了一个小调整,因为它不允许你删除字段中的任何内容而不检查空字符串.我还通过检查第一个字符来添加否定能力if(string ==" - "&& range.location == 0)|| string ==""{return true} return string.toInt()!= nil (2认同)

Ado*_*els 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;
}
Run Code Online (Sandbox Code Playgroud)


小智 8

迅捷5

    //MARK:- UITextFieldDelegate

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
    let allowedCharacters = "1234567890"
    let allowedCharacterSet = CharacterSet(charactersIn: allowedCharacters)
    let typedCharacterSet = CharacterSet(charactersIn: string)
    return allowedCharacterSet.isSuperset(of: typedCharacterSet)
}
Run Code Online (Sandbox Code Playgroud)

您现在只需点击 1234567890 即可


iDe*_*Dev 7

我应用了它,它的工作原理!

-(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;                                                                                                                                     
}
Run Code Online (Sandbox Code Playgroud)