UITextFiled输入那些事

一、主要方法

1、textField代理方法

  • 开始编辑
    点击textField,键盘弹出就会回调此代理方法,开始编辑。返回NO,禁止编辑。
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField;        // return NO to disallow editing.
  • 编辑中
    textField点击键盘按键,就会回调这个代理方法。在这个方法返回NO时,键盘点击输入无效。编辑的过程中我们可以对输入内容进行输入控制等。
    注意这个方法中取到的textField.text并不是最终的内容,而是需要拼上string。
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;   // return NO to not change text
  • 结束编辑
    键盘收起时,结束编辑时候会回调这个代理方法。
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField;          // return YES to allow editing to stop and to resign first responder status. NO to disallow the editing session to end

2、textField添加方法

textField是继承UIControl的,所以可以添加target。这个方法是给textField添加的监控其内容变化的方法。
这个方法中取到的textField.text是真实的最终的输入内容。可以在这个方法中做输入长度限制等。

[self.textField addTarget:self action:@selector(textFieldValueChanged:) forControlEvents:UIControlEventEditingChanged];

二、输入限制

1、自动填充输入内容功能

需求:点击输入框,弹出键盘,并自动填充填充公共的输入内容前缀。点击输入框后,自动填充前缀,如果未输入,键盘收起时候清除自动填充的前缀内容。

例如:点击输入框,需要自动填充前4位“edu_”,在textFieldShouldBeginEditing代理方法中做如下处理

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
    if(textField.text.length<=4)
        textField.text = @"edu_";
    return YES;
}

用户未输入,收起键盘后,自动填充内容需要清除,这个需求和上面是一起的

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    if(textField.text.length<=4) {
        textField.text = nil;
    }
}

2、输入长度限制

需求:输入长度限制16位

实现:在如下方法中做长度限制,建议不要在代理方法中做长度限制,在代理方法中设置会不准确的,选择键盘推荐的文字的时候,代理方法是不会执行的,限制不住。

- (void)textFieldValueChanged:(UITextField *)textField {
    if (textField.text.length >= 12) {
        //长度限制16位
        textField.text = [textField.text substringToIndex:16];
    }
}

3、按钮状态

需求:当输入长度不够时,“下一步”按钮置灰,不可点击,否则按钮可点击并改变颜色。

实现:在内容改变后,做长度限制,有时候会根据长度来设置“下一步”,按钮是否可点击。

- (void)textFieldValueChanged:(UITextField *)textField {
    if (textField.text.length >= 12) {
        //长度限制12位
        textField.text = [textField.text substringToIndex:12];
			//输入长度不够时候按钮置灰不可点击
        self.nextButton.backgroundColor = UIColorSet(82, 204, 144, 1);
        self.nextButton.enabled = YES;
    }
    else {
        self.nextButton.backgroundColor = UIColorSet(220, 244, 232, 1);
        self.nextButton.enabled = NO;
    }
}

4、空格输入限制

系统有提供过滤字符串首位空格的方法:

过滤字符串首尾空格

NSString *text = [textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];

过滤字符串首位空格以及换行

NSString *text = [textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

4.1 过滤首位空格

需求:首位不能输入空格,输入完后自动过滤末尾空格。

实现:首位不能输入空格可在输入时限制,末尾不能输入空格,在输入完之后进行末尾空格过滤。

输入限制控制首位不能输入空格:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
   //限制首位不能输入空格
   if (NSEqualRanges(range, NSMakeRange(0, 0)) && [string isEqualToString:@" "]) {
       return NO;
   }
    return YES;
}

4.2 不能输入空格

需求:过滤首位空格

实现:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
   if ([string isEqualToString:@" "]) {
       return NO;
   }
    return YES;
}

或者:

- (void)textFieldValueChanged:(UITextField *)textField 
{
	textField.text = [textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
}

5、删除键

不管在什么情况下都需要支持删除,直接在代理方法中判断如果是删除操作,一律返回YES即可。

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
	//删除键
	if ([string isEqualToString:@""]) {
	   return YES;
	}
    return YES;
}

6、表情限制

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
	//删除键
	if ([string isEqualToString:@""]) {
	   return YES;
	}
	//不能输入表情
   if ([[[textField textInputMode] primaryLanguage] isEqualToString:@"emoji"] ||
       ![[textField textInputMode] primaryLanguage]) {
       return NO;
   }
   return YES;
}

7、纯数字

需求:密码什么的需要输入纯数字这种需求。

这里创建一个筛选条件,09的闭集,invertedSet方法“取反”,得到的集合是非[09]之外的所有字符集合。

_numberSet = [[NSCharacterSet characterSetWithCharactersInString:@"0123456789"] invertedSet];
  • 在textFieldValueChanged方法中做限制
- (void)textFieldValueChanged:(UITextField *)textField {
    //只能输入纯数字
    textField.text = [[textFiled.text componentsSeparatedByCharactersInSet:_numberSet] componentsJoinedByString:@""];
}
  • 在代理方法中限制
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    //删除键
    if ([string isEqualToString:@""]) {
        return YES;
    }
    //只能输入纯数字
    NSString *filterString = [[string componentsSeparatedByCharactersInSet:_numberSet] componentsJoinedByString:@""];
    if ([filterString isEqualToString:@""]) {
        return NO;
    }
    return YES;
}

在代理方法中做限制会出bug,当用户选择键盘提示文字时,代理方法是不会执行的,也就监听不到输入的内容变化。

三、NSPredicate 和 NSCharacterSet

对于输入限制可以使用NSCharacterSet类,通过-componentsSeparatedByCharactersInSet:方法将数字提取出来,返回一个数组,然后将这个数组通过-componentsJoinedByString:方法组合成一个新的字符串。
因为数组中都是数字,所以组合成的字符串也是由数字组成的字符串。

这里手机号和验证码输入这样限制,加上将键盘设置成UIKeyboardTypePhonePad是可行的,但是昵称和输入限制是存在风险的,是有bug的。

苹果系统键盘顶部会有输入时提示文字,当用户选择键盘上方弹出的提示输入文本时,这个代理方法是不会执行的,就会出bug。

出现上面的问题的主要原因是,选择键盘提示的文本,此代理不会被执行,也就监听不到输入内容的合理性。

解决这个问题,将限制统一放在-textFieldValueChanged:方法中去过滤特殊字符,这样就很保险,不会出bug了。

- (void)textFieldValueChanged:(UITextField *)textField {
    if (textField == self.nameTextFiled) {
        //昵称16位长度限制
        if (textField.text.length >= 16) {
            textField.text = [textField.text substringToIndex:16];
        }
    }
    else if (textField == self.phoneTextFiled) {
        //手机号12位长度限制
        if (textField.text.length >= 12) {
            textField.text = [textField.text substringToIndex:12];
        }
        NSString *filterString = [[textField.text componentsSeparatedByCharactersInSet:[[NSCharacterSet characterSetWithCharactersInString:@"0123456789"] invertedSet]] componentsJoinedByString:@""];
        textField.text = filterString;
    }
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    //删除键
    if ([string isEqualToString:@""]) {
        return YES;
    }
    //限制首位不能输入空格
    if (NSEqualRanges(range, NSMakeRange(0, 0)) && [string isEqualToString:@" "]) {
        return NO;
    }
    //限制表情
    if ([textField.textInputMode.primaryLanguage isEqualToString:@"emoji"]) {
        return NO;
    }
    if (![[textField textInputMode] primaryLanguage]) {
        return NO;
    }
    //中文、英文、字母
    if (textField == self.nameTextFiled) {
        NSString *pattern = @"^[➋➌➍➎➏➐➑➒a-zA-Z\u4E00-\u9FA5\\d]*$";
        NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];
        if (![pred evaluateWithObject:string]) {
            return NO;
        }
    }
    
    return YES;
}

推荐阅读

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Morris_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值