iOS 限制UITextField输入字符

开篇

之前做过一个即时通信的项目,需要限制输入框文本的字符个数,当时从网络上搜寻了几个方法,解决了需求,但是网络上的解决办法不是很全面;今天又遇到一个限制搜索框UISearchBar输入字符个数的问题,所以就就想把字符限制这个问题做的完整彻底一点,下面我提出几个问题,然后一一再做解答,看看你在做字符限制的时候有没有遇到同样问题。在提出这几个问题之前,我先介绍几个方法:

- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text

这个方法是UISearchBar的代理方法,在文本替换之前触发,返回值文BOOL类型,如果返回YES,就替换;反之,则不替换。

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText

这个方法是UISearchBar的代理方法,在文本输入完成之后触发,返回值为空(没有返回值)。

我们要做字符限制的工作就在这两个回调方法中实现;姑且,我们把第一个方法称为方法一,第二个方法称之为方法二,下文中提到的方法一和方法二,就代表这两个方法。

PS:解释一下为什么我这里用的是UISearchBar的代理方法,而不是UITextField的代理方法,这是因为我研究时用的就是UISearchBar,因此,在写这篇博客的时候就用了UISearchBar,而不是UITextField;但是,UISeachBar中的输入框其实也是UITextField,所以用UISearchBar做输入字符限制研究也是一样的,最后我会对与UITextField不同的地方做说明。好,现在让我们进入正题。

问题

1. 只在方法一中做字符限制,在中文输入法下做联想输入时会出现什么情况

2. 只在方法一中做字符限制,在粘贴字符到文本框中时会出现什么问题

3. 只在方法二中做字符限制,在中文输入法下,高亮输入时会有什么问题

现在我已经把问题,提出了,下面我们就来解决这些问题。

最简单的限制输入字符的办法就是在统计输入的字符时不区分英文和汉字,如下示例:

- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {

    UITextField* textField = [_searchBar valueForKey:@"_searchField"];

    if (textField.text.length > kMaxLength) {
                textField.text = [textField.text substringToIndex:kMaxLength];
            }

    return YES;

}

这样做就会出现我提出的问题1和问题2,当在中文输入法下输入时,选中联想出来的字符是不会调用这个方法的,因此统计字符个数的任务就失败了;同理,粘贴文本时也不会调用这个方法。那如何解决这两个问题呢?就是找一个方法,在这两种情况下仍然可以调用该方法;显然,我提到的方法二就起作用了,现改变如下:

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {

    UITextField* textField = [_searchBar valueForKey:@"_searchField"];

    if (textField.text.length > kMaxLength) {
                textField.text = [textField.text substringToIndex:kMaxLength];
            }

}

但是,这样做又会出现我上面提到的问题3,在中文输入法下输入字符时,高亮的字符输入不会调用这个方法;因此统计字符输入还是有点小问题。那如何处理才能达到我们的目的呢?现在我把代码做如下更改:

- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {

    if (text.length == 0) {
            return YES;
       }

    NSString *lang = [[UITextInputMode currentInputMode] primaryLanguage]; // 键盘输入模式
        if ([lang isEqualToString:@"zh-Hans"]) { // 简体中文输入,包括简体拼音,健体五笔,简体手写

        UITextField* textField = [_searchBar valueForKey:@"_searchField"];

        if (textField.text.length > kMaxLength) {
                    return NO;
               }

     }

    return YES;

}

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {

    UITextField* textField = [_searchBar valueForKey:@"_searchField"];

    if (textField.text.length > kMaxLength) {
                textField.text = [textField.text substringToIndex:kMaxLength];
            }

}

好,现在提到的三个问题都得到了解决。

拓展

如果统计的字符要区分中英文,那可以这样做:

- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {

    if (text.length == 0) {
            return YES;
       }

    NSString *lang = [[UITextInputMode currentInputMode] primaryLanguage]; // 键盘输入模式
        if ([lang isEqualToString:@"zh-Hans"]) { // 简体中文输入,包括简体拼音,健体五笔,简体手写

        UITextField* textField = [_searchBar valueForKey:@"_searchField"];

        if (textField.text.length > kMaxLength) {
                    return NO;
               }

     }

    return YES;

}

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {

    NSString* text = [self textLength:searchText];
        searchBar.text = text;

}

- (NSString* )textLength:(NSString *)text//计算字符串长度
{
    int number = 0.0;
    for (int index = 0; index < [text length]; index++)
    {
        NSString *character = [text substringWithRange:NSMakeRange(index, 1)];
        
        if ([character lengthOfBytesUsingEncoding:NSUTF8StringEncoding] == 3) {
            number+=2;
        } else {
            number++;
        }
        if (kMaxLength == number) {
            return [text substringWithRange:NSMakeRange(0, index + 1)];
        }
    }
    return text;
}

这样一个中文就代表两个英文,这个可以根据需要自己更改。

最后说一下UITextField和UISearchBar不同的地方,其实就是代理方法不一样,方法- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 的作用同方法一;而UITextField中没有与方法二作用相同的方法,但是它由一个通知UITextFieldTextDidChangeNotification,这个通知的作用同方法二,因此只要注册这个通知,实现方法二中的代码即可。还有一点需要这一的是,使用完通知之后要记得移除通知。(PS:lengthOfBytesUsingEncoding:要想学习一些编码知识可以参看我的另一篇文章http://www.cnblogs.com/wfwenchao/p/4795268.html

至此限制输入字符的全部工作就完成了。

时间: 2024-10-15 01:34:26

iOS 限制UITextField输入字符的相关文章

iOS中UITextField输入判断小数点后两位

在输入金额的UITextField中,要给予三个规则的判断 1. 只能输入数字(可以通过设置键盘类型为Decimal Pad) 2. 小数点只能有一个 3. 小数点后最多有两位数字 (可以通过正则表达式或者长度判断) 2. 和3. 的代码 (首先引入UITextFieldDelegate,指定代理为自己) - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacem

iOS输入框UITextField输入限制

设置 delegate 1. 输入长度限制: - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { if (textField == self.liveThemeTextField) { //这里的if时候为了获取删除操作,如果没有次if会造成当达到字数限制后删除键也不能使用的后果. if (ran

iOS 富文本格式字符 以及处理iOS8下textview设置富文本后输入bug

iOS的富文本设置,在iOS8下在textView的代理方法中设置textview的attributedText时,会出现富文本格式未加到text上的情况,可以在初始化时将文本属性赋给textview的typingAttributes.代码如下: NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.lineSpacing = 7;// 字体的行间距 UIF

[转]iOS中UITextField 使用全面解析

001//初始化textfield并设置位置及大小002  UITextField *text = [[UITextField alloc]initWithFrame:CGRectMake(20, 20, 130, 30)];003  004//设置边框样式,只有设置了才会显示边框样式 005  text.borderStyle = UITextBorderStyleRoundedRect;006 typedef enum {007    UITextBorderStyleNone,008   

IOS的UITextField,UIButton,UIWebView的一些属性介绍和IOS图片资源的使用技巧

有时候UI给开发的资源跟实际的frame不一致,这个时候我们就要去拉伸图片 UIImage* image = [[UIImage imageNamed:@"text_field_bg.png"] stretchableImageWithLeftCapWidth:20 topCapHeight:0]; //stretchableImageWithLeftCapWidth使图片有拉伸效果 UITextField的属性介绍: UITextField* field = [[UITextFiel

UItexfile实时验证输入字符

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string; { NSString * toBeString = [textField.text stringByReplacingCharactersInRange:range withString:string]; UITextField *loginPas

限制 UITextField 输入长度

限制 UITextField 输入长度 标签(空格分隔): UITextField UITextField 是 iOS 中最常用的组件之一.关于它也有各种各样的需求,这些需求是它本身没有提供相应的API的.限制输入框文本长度是常见的需求,UITextField 本身也并没有为此提供API.本文尝试给其加入这个功能. 1.通过 delegate 来实现 限制 UITextField 的输入字数,首先想到的是 UITextFieldDelegate,通过实现这个协议来实现需求: - (BOOL)te

怎么判断UITextField 输入为空 输入全为空格

手机平台的自动化测试工具很多,之前研究过了安卓和苹果的原生自动化测试框架,经一些同事介绍,貌似Appium是个不错的工具. 想记录一下研究的结果,也算是篇干货的文章 在网上也看了一些视频,个人认为这个自动化测试的特点就是 1. 多编程语言支持 相对于传统的IOS UIautomation只能支持js语言,Appium起到了一个翻译的作用,它其实是一个CS架构,服务器和IOS模拟器或真机直接通讯,客户端和服务器之间用HTTP协议进行交互,所以客户端用什么语言其实不重要.下面会有一个python编程

限制UITextField输入内容的长度

一.前言 今天做手机号输入限制长度,例如我的textfield只能输入11位,如果再多输入的话就不再textfield中显示,只显示11位的手机号. 如果用ReactiveCocoa的话,这个很好解决.但是项目中没有引入该类库,所以只能手动的取完成了. 二.实现原理 先看代码: // // ViewController.m // Test // // Created by zhanggui on 15/12/28. // Copyright © 2015年 zhanggui. All right