UITextField 的初始键盘动画的超慢滞后/延迟

Posted

技术标签:

【中文标题】UITextField 的初始键盘动画的超慢滞后/延迟【英文标题】:Super slow lag/delay on initial keyboard animation of UITextField 【发布时间】:2012-03-10 13:14:00 【问题描述】:

好吧,这个问题让我发疯了。

触摸我的UITextField 后,键盘弹出大约需要 3-4 秒。这仅在应用启动后第一次弹出键盘时发生,之后动画立即开始。

一开始我以为是加载太多图片的问题,或者我的UITableView,但是我刚刚创建了一个只有UITextField的全新项目,我仍然遇到这个问题。我正在使用 ios 5、Xcode 4.2 版,并在 iPhone 4S 上运行。

这是我的代码:

#import "ViewController.h"

@implementation ViewController

- (void)viewDidLoad 
    [super viewDidLoad];

    UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 20, 280, 30)];
    textField.borderStyle = UITextBorderStyleRoundedRect;
    textField.delegate = self;
    [self.view addSubview:textField];


@end

这是所有应用程序的共同问题吗?

现在,我可以让它变得更好的唯一方法是让textFieldviewDidAppear 中成为/辞职第一响应者,但这并不能完全解决问题 - 它只是将延迟加载到视图而是加载。如果我在视图加载时立即单击textField,我仍然会遇到问题;如果我在视图加载后等待 3-4 秒再触摸 textField,我不会得到延迟。

【问题讨论】:

【参考方案1】:

在您实施任何奇特的技巧来解决此问题之前,请尝试以下操作:停止调试会话,关闭应用程序的多任务处理,从计算机上拔下您的设备并通过点击其图标正常运行应用程序。我至少见过两种情况,其中延迟仅在设备插入时发生。

【讨论】:

这是我在运行 iOS 8.1 的 iPhone 5 上的正确答案——我遇到了第一个键盘大约 1 秒的延迟。 是的,只有在调试时才会出现滞后。很奇怪。 谢谢。这个问题在 iOS 9.1/Xcode 7.1、Swift 2.1 上仍然存在。 FYVM 苹果,FYVM。 90 分钟的最后期限我负担不起。如果可以的话,20 票。仍然存在于 iOS9.2/Xcode 7.2 这正是我的问题所在。从我的 Mac 上拔下电源后,没有延迟 (ios9) xcode 7.2【参考方案2】:

所以问题不仅限于我之前认为的第一次安装,而是每次启动应用程序时都会发生。这是我完全解决问题的解决方案。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
  // Preloads keyboard so there's no lag on initial keyboard appearance.
  UITextField *lagFreeField = [[UITextField alloc] init];
  [self.window addSubview:lagFreeField];
  [lagFreeField becomeFirstResponder];
  [lagFreeField resignFirstResponder];
  [lagFreeField removeFromSuperview];

【讨论】:

漂亮而简单的@Vadoff - 这是下面给出的 UIResponder+KeyboardCache 示例的内联版本 这应该由操作系统处理......但是哦,好吧:/ 谢谢!不幸的是,问题仍然存在于 ios8 上,但这种解决方法仍然可以解决它 @Vadoff 解决方案有效,但有 2 个缺点:1)我有大约 1 秒的额外应用程序加载时间; 2) 收到内存警告(但不是一直)。我试图在viewDidLoad中将此代码添加到UIViewController,但没有效果,也许我做错了什么?如果可能的话,您能否编辑您的答案并为视图控制器添加代码。 这是正确答案并且有效的事实让我哭了。应用此技巧后,我不得不洗澡。【参考方案3】:

是的,我在最新的 iPhone 4s 上也有几秒钟的延迟。不要惊慌。由于某些原因,它只会在第一次在 Debug 中从 Xcode 加载应用程序时发生。当我发布时,我没有得到延迟。算了吧……

【讨论】:

这是由于优化级别:Fastest, Smallest [-Os]。您可以在 Build Settings > Optimization Level 上更改它【参考方案4】:

这是一个已知问题。

预加载键盘似乎很有希望。检查Preloading the UIKeyboard.

一些额外的阅读材料:

Initial iPhone virtual keyboard display is slow for a UITextField. Is this hack around required?

UITextField keyboard blocks runloop while loading?

http://www.iphonedevsdk.com/forum/iphone-sdk-development/12114-uitextfield-loooong-delay-when-first-tapped.html

【讨论】:

谢谢,许多链接提到延迟大约是“在旧 iPhone 上 1 秒”、“在 3g 上不那么明显”和“在新设备上立即加载”,但我正在经历在 iphone 4s 上延迟更长的 3-4 秒。接下来我会尝试预加载键盘,但我担心可能是其他问题(可能是 ios5 或我的 xcode 版本?)。 您是否尝试过 UITextField 和键盘在本机应用程序中的行为方式?确保在此测试之前将其从内存中删除(双击主页按钮...)。您发布的这段代码没有任何问题,而且 3-4 秒确实看起来很多 - 太多了。我从未尝试过这种预加载,但它看起来是唯一的解决方法。 是的,地图的搜索文本字段在启动后单击时会立即调出键盘。我从内存中删除它并尝试了几次,每次都是即时的。我不知道为什么我的这么慢。 刚刚对我的一个使用 UITextField 的应用程序进行了测试 - 延迟应该非常小。您发布的代码看起来不错,因此必须有其他东西阻碍了主线程。这可能是发布臭名昭著的 Instruments 的好时机。 好的,对于其他似乎有这个问题的人。我发现它只发生在第一次从 xcode 在 iphone 上更新应用程序时。一旦应用程序加载到 iphone 上,对该应用程序的任何进一步使用都将导致正常行为(我从内存中删除了几次程序/重新启动了我的 iphone 以确保)。【参考方案5】:

您可以在 Swift 中使用 Vadoff 的解决方案,方法是将其添加到 didFinishLaunchingWithOptions:

// Preloads keyboard so there's no lag on initial keyboard appearance.
let lagFreeField: UITextField = UITextField()
self.window?.addSubview(lagFreeField)
lagFreeField.becomeFirstResponder()
lagFreeField.resignFirstResponder()
lagFreeField.removeFromSuperview()

它在 iOS 8 中对我有用。

【讨论】:

【参考方案6】:

块中的代码添加到主队列并异步运行。 (不要锁定主线程)

dispatch_async(dispatch_get_main_queue(), ^(void)
      [textField becomeFirstResponder];
 );

【讨论】:

尝试添加文字解释来描述您的代码为何有效,而不仅仅是提供它以便其他人可以从中学习。 这段代码实际上阻塞了主线程,你在主队列上调度...... 你知道dispatch_async/dispatch_sync的区别吗?你认为 [textField becomeFirstResponder];主线程很难吗? @Spetruk 调用 dispatch_async 的线程没有被阻塞,但是你实际运行代码的线程肯定被阻塞了。单个线程不能同时做两件事,所以这段代码阻塞了主线程(因为 dispatch_get_main_queue),但不会阻塞调用 dispatch_async 的线程。 @Kevin 但有些东西阻塞了主线程,因此键盘动画不起作用。我同意你的看法,但我认为,在 appDelegate 中使用 textFiled 的解决方案很难闻。【参考方案7】:

见this answer。他们建议UIResponder+KeyboardCache。这很简单而且很棒。在 iOS 7 上测试。

【讨论】:

【参考方案8】:

通过在 UITextField 上使用系统字体而不是自定义字体解决了一个相关问题,即 UIViewController 呈现速度慢。也许使用系统字体也​​可以解决这个问题?

【讨论】:

【参考方案9】:

这个错误似乎在 iOS 9.2.1 中得到修复。自从升级我的设备后,当我的设备连接到我的计算机时,我在点击文本字段和出现键盘之间不再有延迟。

【讨论】:

它似乎在 iPhone 上已修复,但我在 iPad 上仍有延迟。【参考方案10】:

此选择的答案会导致 iOS 11 上的 BAD_EXC 崩溃 - 从应用中删除以修复

【讨论】:

【参考方案11】:

您可以在 viewController 的视图加载后添加以下代码,例如 viewDidAppear.Not just application:didFinishLaunchingWithOptions:

UITextField *lagFreeField = [[UITextField alloc] init];
[self.window addSubview:lagFreeField];
[lagFreeField becomeFirstResponder];
[lagFreeField resignFirstResponder];
[lagFreeField removeFromSuperview];

【讨论】:

以上是关于UITextField 的初始键盘动画的超慢滞后/延迟的主要内容,如果未能解决你的问题,请参考以下文章

像键盘一样显示UIPickerView,没有UITextField

怎样在键盘顶部添加UITextField和一个UIButton??

弹出键盘时如何为 UITableView 设置动画?

键盘出现时UITextField上移【Swift】

键盘出现时向上移动 UITextField 和 UITableView

成为没有动画的第一响应者