【问题标题】:How can I speed up becomeFirstResponder?如何加快 becomeFirstResponder 的速度?
【发布时间】:2013-07-20 14:54:15
【问题描述】:

第一次调用 becomeFirstResponder 时,速度很慢。 Instruments 的测量时间约为 160 毫秒……当它加载​​完所有必须加载的内容以使键盘出现在屏幕上时,键盘就出现了!杀死大部分流畅的动画。

然而第二次,它的速度非常快!只需 2 毫秒!

那么,我可以这样做吗?

【问题讨论】:

  • 你的becomeFirstResponder 一直在做什么!?
  • 我个人注意到,如果您有额外的键盘,尤其是表情符号键盘,则键盘需要额外的时间。我正在用英文、西班牙文、日文和表情符号键盘测试键盘的框架,但我总是注意到速度大幅下降。
  • 在这里查看@Vadoff 的答案-stackoverflow.com/a/20436797/558575

标签: ios objective-c uitextfield


【解决方案1】:

使用 GCD

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// heavy lifting here
    dispatch_async(dispatch_get_main_queue(), ^{
        [someTextField becomeFirstResponder];
    });
});

这最初并没有按预期工作,但在将 GCD 应用到后台发生的一些“提升”之后它确实如此。就我而言,这是一个滚动视图

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// heavy lifting here
    dispatch_async(dispatch_get_main_queue(), ^{
        [_tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
    });
});

【讨论】:

  • 第三个版本除了可能延迟becomeFirstResponder直到下一次通过事件循环之外没有做任何事情。所有的工作仍然在主线程上完成。第一个解决方案非常脆弱和丑陋。第二个解决方案似乎是一个非解决方案;它似乎并没有真正改变任何东西。
  • 第三种解决方案确保它异步运行。做与我在背景上做的一样的提升,确保他们没有踩到每个人的脚趾。结果是有点延迟,是的,但不会影响动画的流畅度。我无法预测触发 becomeFirstResponder 所需的时间,所以这成为了一个更优雅的解决方案。我将更新答案并删除解决方案 1 和 2。
  • 你不能在主线程上异步运行一些东西并且不能阻塞或延迟事件循环。如果它解决了问题,那是因为它是在当前通过主事件循环之后的下一个 pass 中完成的;您可以使用延迟为 0.0 或 performSelector:withObject:afterDelay:0.0... 的 dispatch_after() 并获得相同的结果,而无需额外的块排队。 (而且,如果这确实解决了问题,那么......整洁!注意!)
  • 那么在这种情况下,我仍然不确定为什么要修复。当我需要同时做两件事时,我会这样做,比如同时触摸和动画。我想这不像是调度线程。延迟后的 performSelector 在不同的时间给出了非常不同的结果。我会尝试 dispatch_after(),但现在它就像一个魅力 ^^
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-01-26
  • 2015-11-02
  • 2014-10-04
  • 2011-06-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多