web-dev-qa-db-ja.com

BecomeFirstResponderが機能しないのはなぜですか?

AGWindowView を使用してモーダルを追加しました。 (IBを使用して作成された)モーダルビュー内に、テキストフィールドがあります。テキストフィールドはコンセントに接続されています。

これは機能しません:

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

becomeFirstResponderの呼び出しが機能せず、キーボードが表示されません。

これは機能します:

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

ただし、performSelector:withObject:afterDelayを使用して手動でメッセージを送信した場合は機能します。実行時までこのメソッドが決定されないのはなぜですか?

22
Ravi

どうやらiOS7では、ビュー/オブジェクトがビュー階層/ウィンドウにまだアタッチされていないようです。したがって、オブジェクトに対するメソッドの呼び出しは失敗します。遅延を設定し、それが機能している場合、その瞬間にオブジェクトがウィンドウにアタッチされます。

アップルによると、

現在のレスポンダが最初のレスポンダの状態(canResignFirstResponder)に再署名でき、新しいレスポンダが最初のレスポンダになることができる場合にのみ、レスポンダオブジェクトが最初のレスポンダになります。

このメソッドを呼び出して、ビューなどのレスポンダーオブジェクトを最初のレスポンダーにすることができます。ただし、ビュー階層の一部である場合にのみ、そのビューで呼び出す必要があります。ビューのwindowプロパティがUIWindowオブジェクトを保持している場合、それはビュー階層にインストールされています。 nilを返す場合、ビューは任意の階層から切り離されます。

詳細は IResponder Class Reference を参照してください。

7
βhargavḯ

最初の方法と2番目の方法の間にはbigの違いがあります。

performSelector:withObject:afterDelay:delayパラメータごと

メッセージが送信されるまでの最小時間。遅延を0に指定しても、セレクターがすぐに実行されるとは限りません。セレクタは引き続きスレッドの実行ループのキューに入れられ、できるだけ早く実行されます。

2番目のメソッドは適切な時間まで待機し、becomeFirstResponderを実行します。

1
fujianjin6471