iOS

输入框切换键盘卡顿的解决办法

在不断填坑中前进。。

Posted by 三十一 on July 8, 2017

输入框切换键盘卡顿的解决办法

今天开发碰到一个问题: 有两个输入框,一个输入手机号码、一个输入验证码。 客户要求:手机号输入框输入满11位时,切换到验证码输入框。

很常见的需求,也很好解决,观察输入框内容的变化,然后切换键盘响应:

    //监听位数
    if (field.text.length >= 11) {
        dispatch_async(dispatch_get_main_queue(), ^{
            //输入框取消响应
            [field resignFirstResponder];
            //验证码输入框 响应键盘
            [self.codeField becomeFirstResponder];

        });
     }

很愉快的提交了代码,但是测试的小伙伴告诉我,键盘切换的时间有卡顿。????一脸懵逼!!

这也会卡?

然后想到了是不是因为动画引起的问题? 更改如下:

  //监听位数
    if (field.text.length >= 11) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [UIView performWithoutAnimation:^{
                //输入框取消响应
                [field resignFirstResponder];
                //验证码输入框 响应键盘
                [self.codeField becomeFirstResponder];
            }];
        });
     }

还是不行,是在没有办法了,最后搜索到这样一个答案: stackoverflow

A responder object only becomes the first responder if the current responder can resign first-responder status (canResignFirstResponder) and the new responder can become first responder. You may call this method to make a responder object such as a view the first responder. However, you should only call it on that view if it is part of a view hierarchy. If the view’s window property holds a UIWindow object, it has been installed in a view hierarchy; if it returns nil, the view is detached from any hierarchy.

[txtAddNew performSelector:@selector(becomeFirstResponder) withObject:nil afterDelay:0];

心想这样总可以了吧。

    [field resignFirstResponder];
    [self.codeField performSelector:@selector(becomeFirstResponder) withObject:nil afterDelay:0];

。。。 还是不行。。

最后把 [field resignFirstResponder]; 这样代码注释掉才可以。

最终版本:

    //监听位数
    if (field.text.length >= 11) {
        //切换键盘响应
        //解决切换键盘卡顿
        [self.codeField performSelector:@selector(becomeFirstResponder) withObject:nil afterDelay:0];
     }

猜测应该是键盘所在的 window 切换导致的这个问题。

如果先取消第一个输入框的响应,再让第二个输入框响应, 这样的话会先把当前键盘所在的 window 销毁,然后创建新的 window,就会导致卡顿。

如果不先取消第一个键盘的响应,就不会销毁 window 也不会创建新的 window ,就不会卡顿。有时间了写个 demo 验证下。

好尴尬,在模拟器上测试。

2017-07-08 17:45:07.888 TestBecomeFirstResponder[14397:582182] 窗口 = 0x7f8cc841cd70
2017-07-08 17:45:07.888 TestBecomeFirstResponder[14397:582182] 窗口 = 0x7f8cc85b2630
2017-07-08 17:45:07.889 TestBecomeFirstResponder[14397:582182] 窗口 = 0x7f8cc847e910
2017-07-08 17:45:07.889 TestBecomeFirstResponder[14397:582182] 




2017-07-08 17:45:08.973 TestBecomeFirstResponder[14397:582182] 窗口 = 0x7f8cc841cd70
2017-07-08 17:45:08.973 TestBecomeFirstResponder[14397:582182] 窗口 = 0x7f8cc85b2630
2017-07-08 17:45:08.974 TestBecomeFirstResponder[14397:582182] 窗口 = 0x7f8cc847e910
2017-07-08 17:45:08.974 TestBecomeFirstResponder[14397:582182] 

窗口都没有变化。。。这让老夫如何是好!