2014-09-26 34 views
0

我正在展示另一個UIViewController的UIViewController。所呈現的視圖控制器實現viewDidAppear這樣:UITextField如何在viewDidAppear中調用becomeFirstResponder減慢當前動畫速度?

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

但是,如果我實現viewDidAppear這樣的:

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

有演示文稿中的動畫沒有明顯的延遲。

我的主要問題是,有沒有人知道是否有另一種方式使文本字段成爲第一響應者,而不會延遲我目前的動畫?我不認爲第二種解決方案是乾淨的。我依賴於執行選擇器的一些實現細節來獲得我想要的功能。我寧願不。

我也很好奇,爲什麼第一種方法會出現這樣的延遲,以及第一種方法與第二種「幕後」方法的區別。

編輯:也許值得注意的是,當前視圖控制器動畫中的延遲僅出現在第一次呈現時。

回答

2

這是一個已知的問題。看看here

解決它只需添加到您的AppDelegate:

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

這將加載在應用程序啓動,其緩存鍵盤使得它負載上隨後出現較快即文本查看一個無形的鍵盤。

雖然這將修復它,它會讓你的應用程序加載速度較慢(甚至可能是你的程序崩潰,因爲它需要長期)

另一個選項是將becomeFirstResponder分派到主線程,這將使它在推/模態動畫完成後運行(基本上與第二種解決方案相同,但方式更清潔):

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

我會選擇第二個。

反正回答你的第二個問題:

-performSelector:withObject:afterDelay:有0.0秒的延遲不立即執行給定的選擇,但目前Runloop週期結束後和給定的延遲後,而不是執行它。

因此,使用-performSelector:withObject:afterDelay: UI在當前Runloop循環中發生更新,即在這種情況下,視圖被壓入,然後執行選擇器(並使您的textView firstResponder等)使一切順利。

來源:Apple Dev Docsthis Thread Answer

希望我能幫上忙。