输入框切换键盘卡顿的解决办法
今天开发碰到一个问题: 有两个输入框,一个输入手机号码、一个输入验证码。 客户要求:手机号输入框输入满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]
窗口都没有变化。。。这让老夫如何是好!