简体   繁体   English

UITextField如何调用viewDidAppear中的成为firstResponder来减慢当前动画的播放速度?

[英]How come UITextField calling becomeFirstResponder in viewDidAppear slows down the present animation?

I am presenting a UIViewController from another UIViewController. 我从另一个UIViewController介绍一个UIViewController。 The presented view controller implements viewDidAppear as such: 呈现的视图控制器将viewDidAppear实现为:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [self.addressTextView becomeFirstResponder];
}

However, if I implement viewDidAppear like this: 但是,如果我这样实现viewDidAppear:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [self.addressTextView performSelector:@selector(becomeFirstResponder) withObject:nil afterDelay:0.0f];
}

There's no noticeable delay in the presentation animation. 演示动画没有明显的延迟。

My main question is, does anyone know if there's a another way to make the text field become first responder, without delaying my present animation? 我的主要问题是,有没有人知道是否还有另一种方法可以使文本字段成为第一响应者,而不会延迟我现在的动画? I do not consider the second solution clean. 我不认为第二种解决方案是干净的。 I'm relying on some implementation detail of how perform selector works to get the functionality I want. 我依赖于执行选择器如何工作的一些实现细节,以获取所需的功能。 I'd rather not. 我宁愿不。

I'm also curious why there's such a delay with the first method and how the first method differs from the second method "behind the scenes". 我也很好奇为什么第一种方法会有这样的延迟,以及第一种方法与“幕后”第二种方法有何不同。

edit: It's perhaps worth noting that the delay in the present view controller animation only occurs the FIRST time it's presented. 编辑:可能值得注意的是,当前视图控制器动画中的延迟仅在它第一次显示时发生。

This is a known problem. 这是一个已知的问题。 Have a look here . 在这里看看。

To Fix it simply add this to your AppDelegate: 要修复它,只需将其添加到您的AppDelegate中:

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

It will load an invisible Keyboard on Application Launch, which caches the keyboard and makes it load faster on subsequent appearances ie your text View. 它将在应用程序启动时加载一个不可见的键盘,该键盘将缓存键盘并使其在随后的外观(即您的文本视图)上更快地加载。

While this will fix it, it will make your Application Load slower(and even possibly crash your application because it takes to long) 虽然可以解决此问题,但会使您的应用程序加载速度变慢(甚至可能会导致应用程序崩溃,因为这需要花费很长时间)

Another options would be to dispatch the becomeFirstResponder to the main Thread which will make it run after the push/modal animation finished (essentially the same as your second solution but way cleaner): 另一个选择是将beginFirstResponder调度到主线程,这将使其在push / modal动画完成后运行(本质上与您的第二个解决方案相同,但更加简洁):

dispatch_async(dispatch_get_main_queue(), ^(void){
  [self.adressTextView becomeFirstResponder];
});

I'd choose the second one. 我会选择第二个。

Anyways to answer your second question: 无论如何回答第二个问题:

-performSelector:withObject:afterDelay: with a delay of 0.0 seconds does not execute the given selector immediately but instead performs it after the current Runloop Cycle finishes and after the given delay. -performSelector:withObject:afterDelay:延迟为0.0秒不会立即执行给定的选择器,而是在当前的Runloop Cycle完成和给定的延迟之后执行它。

Therefore using -performSelector:withObject:afterDelay: the UI has a change of getting updated in the current Runloop Cycle ie in this case the view is pushed, before your selector is performed(and make your textView firstResponder and so on) which makes everything smooth. 因此,使用-performSelector:withObject:afterDelay: UI具有在当前Runloop Cycle中更新的更改,即,在这种情况下,在执行选择器之前将视图推入(并使textView firstResponder等),这使所有过程变得顺畅。

Source: Apple Dev Docs and this Thread Answer 来源: Apple Dev Docs此主题答案

Hope I Could Help. 希望我能帮上忙。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM