iOS 12 在系统中文键盘上使用 AutoFill 会遇到诡异的问题以及解决方案

感谢我们 iOS 团队的赵恒、刘家飞发现此 bug。

640?wx_fmt=jpeg


一. 问题描述

首先,创建一个 textField,使用 addTarget 函数来监听 textField 的 editingChanged 事件。

 
 
  1. lazy var textField: UITextField = {

  2.    let tf = UITextField()

  3.    tf.keyboardType = .numberPad

  4.    tf.textAlignment = .center

  5.    tf.addTarget(self, action: #selector(valueChange(textField:)), for: .editingChanged)

  6.    return tf

  7.  }()

  8.  @objc func valueChange(textField:UITextField)

  9. {

  10.    print("------value change---  \(textFiled.text)  ----")

  11.    if (textFiled.text?.count == 6)

  12.    {

  13.        //do something 和服务器通讯验证用户输入的验证码是否正确

  14.    }

  15. }

如果系统升级到最新的 iOS 12.0,并结合系统中文键盘使用 AutoFill (自动识别短信验证码)的功能,就会发现 valueChange 函数中 "do something" 的这段代码被调用了三次

在 iOS 12 设备上使用系统的 中文(简体)键盘或者 中文(繁体)键盘会打印出以下 log

 
 
  1. ------value change---  Optional("123456")  ----

  2. ------value change---  Optional("123456")  ----

  3. ------value change---  Optional("")  ----

  4. ------value change---  Optional("1")  ----

  5. ------value change---  Optional("12")  ----

  6. ------value change---  Optional("123")  ----

  7. ------value change---  Optional("1234")  ----

  8. ------value change---  Optional("12345")  ----

  9. ------value change---  Optional("123456")  ----

再测试一下系统其他语言的键盘,例如 英文(美国)键盘或者 日文键盘,打印出来的 log

 
 
  1. ------value change---  Optional("")  ----

  2. ------value change---  Optional("1")  ----

  3. ------value change---  Optional("12")  ----

  4. ------value change---  Optional("123")  ----

  5. ------value change---  Optional("1234")  ----

  6. ------value change---  Optional("12345")  ----

  7. ------value change---  Optional("123456")  ----

由此,得出以下结论:

在系统中文键盘上 editingChanged 事件会莫名地多执行 两次

使用 RxSwift 会得到同样的结论,下面是使用 RxSwift 的代码片段:

 
 
  1. textField.rx.text.orEmpty

  2. .subscribe(onNext: { text in

  3.    let count = text.count

  4.    if count == 6 {

  5.      //do something 和服务器通讯验证用户输入的验证码是否正确

  6.    }

  7. })

  8. .disposed(by: bag)


二. bug report

640?wx_fmt=png


640?wx_fmt=png

三. 解决方案

使用 UITextFieldDelegate 来代替原先 editingChanged / RxSwift 的监听事件,具体解决的代码片段如下:

 
 
  1. func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

  2.        if range.location == 5 {

  3.            var text = ""

  4.            if let tfText = textField.text {

  5.                text = tfText + string

  6.            }

  7.            if text.count == 6 {

  8.                //do something 和服务器通讯验证用户输入的验证码是否正确

  9.            }

  10.        }

  11.        return true

  12.    }


关注【Java与Android技术栈】

更多精彩内容请关注扫码

640?wx_fmt=jpeg


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值