iOS17 笔画/五笔键盘下文字输入问题

335 阅读2分钟

问题描述: 前段时间系统升级到iOS17系统,发现在用户输入界面,在切换键到笔画/五笔模式下会导致键盘输入时placeholderLabel显示隐藏异常。

问题定位: 首先,优先定位到- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string方法。

先详细介绍下这个TextField的代理方法,使用的频次颇高,就不详细说了,把官网的说明搬到这里大家再过一遍

  • 方法说明:
    • The text field calls this method whenever user actions cause its text to change.
  • textField
    • The text field containing the text.
  • range
    • The range of characters to be replaced.
  • string
    • The replacement string for the specified range. During typing, this parameter normally contains only the single new character that was typed, but it may contain more characters if the user is pasting text. When the user deletes one or more characters, the replacement string is empty.
  • 返回值
    • YES if the specified text range should be replaced; otherwise, NO to keep the old text.

最开始,项目中的键盘输入逻辑我写一部分伪代码,贴到这里

- (**BOOL**)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

{

    **if** (string.length > 0) {

        placeholderLabel.hidden = **YES**;

    } **else** **if** ((string.length == 0 && textField.text.length == 1) || range.length == textField.text.length) {

        placeholderLabel.hidden = **NO**;

    }

    **return**  **YES**;

}

其实以上代码在iOS17之前的系统完全没有问题,唯一的问题点就是iOS17系统,在切换笔画/五笔键盘下时,每输入一个字符,这个代理方法会走两次。

  • 第一次:所有参数均正常。 -----正常
  • 第二次:string参数异常为空字符串,其他参数正常。 -----异常

这就导致输入第一个字符,第二次走代理方法时,走到了string.length == 0 && textField.text.length == 1这个条件下,placeholderLabel置为隐藏状态了。

  • 尝试1:删除掉string.length == 0 && textField.text.length == 1这个判断条件,因为后边的range.length == textField.text.length条件已经包含了前面的条件,前面的判断没有意义。 结果:当输入第1个字符时,第二次异常string为空此时会走到range.length == textField.text.length这个条件下,placeholderLabel又显示出来了,没有解决问题。
  • 尝试2:改为range.length == textField.text.length && range.length != 0,其中range.length != 0就是为了解决尝试1中的输入第一个字符的情况。

最终解决方案

代码如下:

- (**BOOL**)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

{

   **if** (string.length > 0) {

        placeholderLabel.hidden = **YES**;

    } **else** **if** (range.length == textField.text.length && textField.text.length != 0) {

        placeholderLabel.hidden = **NO**;

    }

    **return**  **YES**;

}

这个问题应该是苹果官方的一个bug,总之能解决了就ok了。不知道后续啥时候能修复。