【iOS】解决UITextField输入限制受中文自动联想影响的问题
想解决问题直接跳转 三、解决UITextField输入限制受中文自动联想影响的问题
一、前言
关于这次需求:UITextField输入限制看起来是个很简单的需求,然而测试还是能测出很多问题,越来越觉得开发时候的UI简直是一个无底洞,问题并不是很难很复杂,但是他总是会在你不可预期的地方突然冒出来。
一点题外话:做了差不多五个月的iOS开发,很惭愧自己还没有接触到深层次一点的内容,接下来要花大概一到两周完成毕业设计,之后可能要找个感兴趣的点去研究一下才行了。
二、UITextField输入限制的基本实现
有两个地方有类似的输入限制需求
A.只支持数字输入,不支持自动联想,限制5位数,输入数字时同一层级的一个按钮title要同时变化
1.首先会想到使用只有数字键盘的样式,即设置UIKeyboardType
试过一两种,参考了其他样式 https://blog.csdn.net/shihuboke/article/details/77430358
发现数字键盘没有带确认/Return/Done健的样式,遂弃用。
最后初始化设置:
//customBtn是TextField的背景按钮,实现点选的效果
self.cmoneyTextField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, customBtn.frame.size.width, customBtn.frame.size.height)];
self.cmoneyTextField.backgroundColor = [UIColor clearColor];
self.cmoneyTextField.font = [UIFont systemFontOfSize:13.f];
self.cmoneyTextField.textColor = [UIColor colorWithRed:(0x66/255.0) green:(0x66/255.0) blue:(0x66/255.0) alpha:1];
self.cmoneyTextField.textAlignment = NSTextAlignmentCenter;
self.cmoneyTextField.keyboardType = UIKeyboardTypeNumbersAndPunctuation;
self.cmoneyTextField.placeholder = @"其他";
[self.cmoneyTextField setValue:[UIColor colorWithRed:(0x66/255.0) green:(0x66/255.0) blue:(0x66/255.0) alpha:1] forKeyPath:@"_placeholderLabel.textColor"];
self.cmoneyTextField.returnKeyType =UIReturnKeyDone;
self.cmoneyTextField.autocorrectionType = UITextAutocorrectionTypeNo;//关闭自动联想
self.cmoneyTextField.delegate = self;
2.为了只支持数字输入且限制5位数,重写 textField:shouldChangeCharactersInRange:replacementString:方法
这个方法调用的时机是每次文本输入后,文本显示前
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{if (textField == self.cmoneyTextField) {//正则判断 只允许数字输入NSString *checkStr = [textField.text stringByReplacingCharactersInRange:range withString:string];NSString *regex = @"^[0-9]*$";NSPredicate *resultStr = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex];if([resultStr evaluateWithObject:checkStr] == NO) {return NO;}if (range.length == 1 && string.length == 0) {return YES;}else if (self.cmoneyTextField.text.length >= 5) {self.cmoneyTextField.text = [textField.text substringToIndex:5];return NO;}}return YES;
}
正则的判断是网上抄的作业,判断了一整串文本,不符合条件就拒绝输入。
第二个判断(range.length == 1 && string.length == 0)可以理解为判断输入是否为删除符。
删除符的原理:个人理解是要在输入时先往文本里面添加一个显示长度为0但是实际算一个长度的占位符,然后在显示时如果遇到删除符则直接删除一个字符,同时删除自身。因此这个判断其实就是为了判断删除符(应该是没有其他的可输入按键有这样的性质,确认键?),避免出现满5位后无法删除的情况。
第三个判断很容易理解了,如果当前已经有5个字符(或以上)了,那么就截剩5个并且拒绝此次输入。
3.接着为了在输入数字后按钮实时变化,监听UITextFieldTextDidChangeNotification通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldChange:) name:UITextFieldTextDidChangeNotification object:nil];
收到通知的时机是在文本显示后,实现方法textFieldChange:
- (void)textFieldChange:(NSNotification *)notification
{self.cmoneyCount = [self.cmoneyTextField.text integerValue];if ([self.delegate respondsToSelector:@selector(scriptRewardCategoryView:withCmoney:)]) {[self.delegate scriptRewardCategoryView:self withCmoney:self.cmoneyCount];}
}
这里使用代理方法让外部VC处理按钮变动事件,没有什么难点。
B.支持中英文和数字,支持自动联想,不能超过24个字符,中文算两个字符
上面所说的时机应该很好理解,所以这个需求也差不多。
计算中文字符这个原本就做了封装,同时其实后台也会对输入进行校验,因此我只要实现不超过24个字符的需求就行了。
textField的设置不再赘述,自动联想打开就好。
还是重写 textField:shouldChangeCharactersInRange:replacementString:方法
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{NSMutableString *text = [textField.text mutableCopy];[text replaceCharactersInRange:range withString:string];if (textField == self.nickNameTextField && [text fl_UnicodeLength] > kXXNickNameMaxLength) {char a = [text characterAtIndex:text.length-1];if(a!= 127){return NO;}}return YES;
}
这次简单粗暴很多:直接拿取了输入的文本的最后一位,在长度已经超出的情况下,最后一位如果不是删除符(ascii十进制127)则直接拒绝这次输入(感觉没有A方法的判断好)。
三、解决UITextField输入限制受中文自动联想影响的问题
讲道理上面的东西应该能够完成需求了,但是都在iOS8,9(12没问题,10,11没有测试)上出现了问题
A.关闭了自动联想,但是在输入一个数字后会出现标点符号的自动联想!
上面是iOS8的表现(iPhone6)
上面是iOS12表现(iPhone6Plus 选错了 无影响)
这里注意,点击联想出来的标点符号是可以输入的!
通过打断点可以发现:
iOS8中文联想出来的标点符号输入,不会触发textField:shouldChangeCharactersInRange:replacementString:方法,但是依然能够发出UITextFieldTextDidChangeNotification通知,实在万幸!
解决方法:
收取文本改变通知后再检查并截断一次文本
- (void)textFieldChange:(NSNotification *)notification
{NSString *t = self.cmoneyTextField.text;if(t.length > 0){ //为ios8中文标点联想做特殊处理char lastChar = [t characterAtIndex:t.length-1];if(lastChar < 48 || lastChar > 57){self.cmoneyTextField.text = [t substringToIndex:t.length-1];}}//... 原有代码
}
这里也是很简单粗暴了,以为关闭了自动联想后,输入数字只会出现中文标点符号,且点击后不能继续操作,因此就直接拿最后一个字符判断,如果不是数字就截去。
B.开启了自动联想,但是中文自动联想不触发textField:shouldChangeCharactersInRange:replacementString:方法
其实大概已经可以猜到,iOS8,9的中文联想应该是和之后版本的中文联想有所区别的(还不完善),它们并不归在联想的设置里面,同时也不会触发文本输出的方法,因此需要在接受到文本改变通知之后补救
针对B情况,在iOS8,9会有可以无限输入联想中文的情况(因为不会进入textField:shouldChangeCharactersInRange:replacementString:方法,也就无法判断长度)
解决方法如下
- (void)textFieldChange:(NSNotification *)notification
{NSString *t = self.nickNameTextField.text;if([t fl_UnicodeLength] > kXXNickNameMaxLength) {self.nickNameTextField.text = [t substringToIndex:self.textFieldForAutoMerge];}self.textFieldForAutoMerge = self.nickNameTextField.text.length;
}
同样接受通知调用textFieldChange方法,判断长度并截取。
这里注意使用一个NSInterger变量textFieldForAutoMerge来记录输入前的文本长度,一旦文本显示超过规定,就把前一次输入全部截取。
就这么多,希望第三部分能给大家有所提示
Good Luck Everyone!
【iOS】解决UITextField输入限制受中文自动联想影响的问题相关推荐
- ubuntu20.04 微信输入不了中文解决办法
关于微信的安装,可以看这篇文章: ubuntu 20.04 安装 微信最新方式 安装后发现输入不了中文,这影响我在码代码的时候和妹子聊天啊 ,这可不行,一定要解决掉! 终端输入: cd /opt/de ...
- 0.54与0.55版本react-native的TextInput在iOS上无法输入中文日文韩文的bug
更新最新版本的react-native,发现最近两版本的TextInput终于出现对ios的不友好.在官网查了下发现 0.54与0.55版本react-native的TextInput在iOS上无法输 ...
- 在win10 系统输入法 输入几下老是自动被禁用解决办法
在win10 系统输入法 输入几下老是自动被禁用, 1.尝试换微软输入法,看看是否会出现同样的问题. 可以通过设置>>时间和语言>>区域和语言>>中文>> ...
- kali-linux 完美解决sublime输入 中文
kali-linux 完美解决sublime输入中文 在kali-linux 完成任何一件事情都是非常高兴的,对于长期使用window系统的人是个巨大的挑战. 对于sublime下载后出现不能输入中文 ...
- 解决 Linux 下 Sublime Text 中文输入
2019独角兽企业重金招聘Python工程师标准>>> 完美解决 Linux 下 Sublime Text 中文输入 完美解决 Linux 下 Sublime Text 中文输入 转 ...
- Appium 解决不能输入中文字符问题
Appium 解决不能输入中文字符问题 Appium版本1.3.3以上. Java: 在capabilities中增加两项设置: capabilities.setCapability("un ...
- 全面解决amule容易崩溃和中文显示、输入的问题(转)
全面解决amule容易崩溃和中文显示.输入的问题(转)[@more@] amule是一个类似windows下的emule的ed2k客户端.ed2k是一种类似于Bittorrent的点对点文件传输协议. ...
- 解决某些情况下输入法中文状态下输入英文
解决某些情况下输入法中文状态下输入英文 KB961503是windows 系统的补丁: 文件大小:560.88KB 漏洞影响:安装本更新程序可解决在使用 Windows Live Messenger( ...
- Linux系统Deepin/Ubuntu解决IDEA输入中文光标无法跟随的问题
Linux系统Deepin/Ubuntu解决IDEA输入中文光标无法跟随的问题 1. 问题描述 2. 问题阐述 3. 解决方案 4. 解决步骤[推荐] (1) 先下载资源 (2)解压出jbr,放到一个 ...
- sql server 改写与插入的切换键,解决sql输入内容会自动把后面的内容替换掉的问题?
当我们修改sql语句时,经常会碰到新输入的内容会自动把后面的内容替换掉,问题的关键就在于insert键.ins(insert)键是改写与插入的切换键. 为什么会按到ins(insert)键 1.Del ...
最新文章
- ffmpeg库编译加文字_使用ffmpeg库编译错误及解决办法
- html制作棋盘,棋盘的制作方法
- 软件包管理 rpm yum apt-get dpkg
- PHP开发环境配置:安装与配置Apache、PHP、MySQL、PhpMyAdmin
- html拖拽模态框,可拖拽的谷歌样式纯javascript模态窗口插件
- 介绍自己以及github注册流程
- gin框架-2-返回是html格式的网页数据
- 【HDU6194】string string string(统计出现k次的子串数目---后缀数组+st表)
- 吉林大学超星MOOC学习通高级语言程序设计 C++ 实验01 顺序程序设计(2021级)
- JEB工具介绍及使用
- UltraEdit 注册机使用激活方法:
- 【Alpha版本】冲刺阶段——Day 1
- 使用属性在 ASP.NET Web API 2 路由创建一个 REST API
- sudo: /etc/sudoers is world writable sudo: no valid sudoers sources found, quitting sudo: 解决方法
- tolua, luaframework环境搭建
- NIO及多线程实现聊天室完整版
- FMC150-两路250Msps AD、两路500Msps DA FMC子卡模块
- 如何把excel里面中文小写数字转换成阿拉伯数字
- IOS版aplayer使用教程_[按键精灵手机版教程]安卓3.0按键使用教程
- AForge.Video.FFMPEG库使用注意事项
热门文章
- SpringBoot(53) 整合canal实现数据同步
- Multi-Task Feature Learning for Knowledge Graph Enhanced Recommendation
- [CVE-2021-45105] Apache Log4j2 漏洞复现与原理详细分析
- Visual Paradigm 顾客旅程地图 (Customer Journey Map)
- 物联网卡是做什么用的
- ROI Pool、ROI Align、PSROI Pool、PrROI Pool
- word-目录突然无法更新解决方法
- 虚幻引擎5改变了游戏,并与Perforce原生集成
- msr830路由器配置虚拟服务器,华三MSR系列路由器(V7)平台家庭宽带配置IPV6
- Win10 添加传统照片查看器