解决 UITextField 密文样式时,重新输入会清空的情况

最近在写代码时发现了一个奇怪的问题,需求是实现一个密文输入的输入框。这个很简单,直接将 UITextFieldisSecureTextEntry 属性设置为 true 即可。但测试同事在测试过程中发现一个问题,就是当密码输入框进行二次编辑的时候,会将上一次输入的内容清空。

比如,我第一次在密码输入框输入 1234,当我点击别的输入框,然后再切回密码输入框进行输入的时候,iOS 系统会将上一次的 1234 直接清空,只显示最新输入的文本。

尝试一:clearsOnBeginEditing

修改这个 bug 的时候,我想起了 UITextField 应该是有个属性可以控制是否在开始编辑的时候清空数据的,上网查了一下,确实有一个属性:clearsOnBeginEditing 。当时很开心,以为修改一下这个属性的值就可以解决这个问题了。结果修改完一运行傻眼了,并没有任何卵用。又上网查了一下才知道:当 UITextFieldisSecureTextEntry 属性为 true 的时候,clearsOnBeginEditing 这个属性是不起作用的,所以将其设置为 false 也是无效的。

尝试二:textField(_:shouldChangeCharactersIn:replacementString:)

既然上面的方式解决不了,那就只能借助 UITextField 的代理方法来进行控制了。方法实现也很简单,就是获取当前 textField 的文本内容,当触发代理方法的时候将保存的文本与输入的文本进行拼接,然后再将合成的文本赋值给 textField 即可。

代码实现:

ini 复制代码
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    NSString *updatedString = [textField.text stringByReplacingCharactersInRange:range withString:string];
    textField.text = updatedString;
    return NO;
}

修改完之后,运行试了一下。文本的内容显示确实正常了,但还是有两个问题:

  • 当光标选中文本中间位置输入时,输入完光标会自动跳到文本末尾,而不是保持在正确的位置
  • 当文本编辑时,不会触发 UIControlEventEditingChanged

最终解决方案

还是在 UITextField 的代理方法里面解决上面发现的两个问题:

ini 复制代码
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    //设置文本
    NSString *updatedString = [textField.text stringByReplacingCharactersInRange:range withString:string];
    textField.text = updatedString;
    //将光标设置到正确的位置
    NSRange selectedRange = NSMakeRange(range.location + string.length, 0);
    UITextPosition* from = [textField positionFromPosition:textField.beginningOfDocument offset:selectedRange.location];
    UITextPosition* to = [textField positionFromPosition:from offset:selectedRange.length];
    textField.selectedTextRange = [textField textRangeFromPosition:from toPosition:to];
    //触发 UIControlEventEditingChanged
    [textField sendActionsForControlEvents:UIControlEventEditingChanged];
    return NO;
}

这就是最终的解决方案了。当然了,Apple 官方既然将密文形式的 UITextField 输入方式设计成这样,应该还是有它的道理的。所以,说服测试同学能接受这种方式才是最好的解决方案。😂

相关推荐
2501_9160088917 小时前
iOS 证书管理最佳实践 从创建到续期的完整指南
android·ios·小程序·https·uni-app·iphone·webview
黑科技iOS上架1 天前
ReactNative入门介绍
经验分享·ios
智塑未来1 天前
鸿蒙系统对比安卓、iOS,核心优势是什么?
android·ios·harmonyos
初雪云1 天前
iOS 上架入门:证书、描述文件、IPA 上传到底是什么关系?
android·ios·自动化·产品经理·iphone
狂热开发者2 天前
用 Typeoff 把会后口述整理成 Markdown 决策记录
人工智能·windows·macos·ios·安卓
2501_916007472 天前
iPad 怎么抓包 从代理模式到暴力抓包的操作方法
android·ios·小程序·uni-app·代理模式·iphone·ipad
2501_915918412 天前
PerfDog 太贵?iOS 性能监控工具的功能对比与选择
android·ios·小程序·https·uni-app·iphone·webview
MDM.Plus2 天前
苹果MDM技术演进:从远程控制到设备信任体系的构建
运维·服务器·安全·ios·mdm·手机店
韩曙亮2 天前
【Flutter】Flutter 进程保活 ③ ( 屏幕常亮设置 | Flutter 禁止息屏、关闭自动锁屏、屏蔽系统屏保 )
android·flutter·ios·屏幕常亮·禁止息屏
2501_915909063 天前
IPA 深度混淆是什么意思?从混淆强度到实际效果的解读
android·ios·小程序·https·uni-app·iphone·webview