将 UITextField 限制为代表月份的 2 位数字

Limiting UITextField to 2 digits representing a month

我创建了一个视图控制器,允许用户输入他们的信用卡信息以继续购买。除了讨厌的年份和月份格式外,一切都很好。更具体地说,月份,要求用户只能输入 2 位数字(使用 'shouldChangeCharactersInRange' 方法很容易做到)加上某种检查,以限制可以在 UITextField 中保留的数字类型。目前,用户可以在里面输入任何 2 位数字(在文本字段中看起来像这样:83 或 21 等)但我只需要允许输入 1-12 中的数字。

在查看堆栈溢出时,我确定有人做过类似的事情,但我一直无法找到任何东西。有人能给我指出正确的方向吗?

里面会放什么?

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    switch (textField.tag)
    {
        case 3: //Month.
            //This allows to tap on a UITextField, even if it already contains 2 digits, and deleting these digits with the delete key with out being thrown out because of 'resignFirstResponder'.
            if (textField.text.length > 1 && !([string length] == 0 && range.length > 0))
            {
                [_textfieldMonth resignFirstResponder];
            }


            //End up with UITextField displaying only from 01 - 12.


            break;

        case 4: //Year.
            break;
    }
}

您可以检查 if/else 条件来检查输入 [yourTextField.text intValue] < 13 && [yourTextField.text intValue] > 0,如果它大于 12 或小于 0,则发出 alertview

if (textField.text.length > 1 && !([string length] == 0 && range.length > 0))
 {
      if([textField.text intValue]<13 &&[textField.text intValue]>0)
      {
        [_textfieldMonth resignFirstResponder];
      }
      else
      {
         UIAlertView *message = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Please make sure you enter a value between 1-12" delegate:nil  cancelButtonTitle:@"OK" otherButtonTitles:nil];
         [message show];
      }
 }

除此之外,如果您进一步将用户输入转换为月份名称,如下所示:

int monthNumber = textField.text; 
NSDateFormatter *df = [[NSDateFormatter alloc] init];
NSString *monthName = [[df monthSymbols] objectAtIndex:(monthNumber-1)];

您问题中的代码(以及另一个答案中的当前代码)的问题是 shouldChangeCharactersInRange 在最近的 typed/pasted/cut/copied 文本实际发送到文本字段之前被调用.您需要查看新文本的内容并进行验证。

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    switch (textField.tag)
    {
        case 3: //Month.
        {
            NSString *value = [textField.text stringByReplacingCharactersInRange:range withString:string];
            int month = [value intValue];
            if (month >= 1 && month <= 12)
            {
                [textField resignFirstResponder];
            }
            break;
        }
        case 4: //Year.
            break;
    }
}

更好的解决方案是在用户实际尝试离开月份字段时等待验证月份条目,并在值无效时阻止他们离开。

这是我所做的,它最终满足了我的需要。

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    switch (textField.tag)
    {
        case 3: //Month.
            if (textField.text.length > 1 && !([string length] == 0 && range.length > 0))
            {
                int intValue = [textField.text intValue];
                if (intValue < 13)
                {
                    [_textfieldMonth resignFirstResponder];
                }
                else
                {
                    textField.text = [NSString stringWithFormat:@"Month"];
                    [_textfieldMonth resignFirstResponder];

                    UIAlertView *message = [[UIAlertView alloc] initWithTitle:@"Error" message:@"This field only accepts numbers from 01 to 12" delegate:self  cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
                    [message show];
                }
            }
            break;
        case 4: //Year.
            break;
    }
}