30

Objective-C の「ModalForWindow」言語と、その後のモーダル セッションの使用方法に関する混乱を解消するには、かなりの実験が必要でした。おそらく、次のヒントは誰かの時間を節約するでしょう:

(概念に慣れていない場合: ウィンドウ (通常はパネル) がモーダルで実行されると、ウィンドウが閉じられるまで、アプリの他の部分が応答しなくなります。)

「ModalForWindow」は、さまざまな状況でさまざまなことを意味します。xib によって定義されたパネルを表示するために loadNibNamed を使用していて、モーダルで実行したい場合は、表示されたらこれを呼び出します。

// Make panelReviewImports modal, so that no other part of app will respond.
[[NSApplication sharedApplication] runModalForWindow:self.panelReviewImports];

解雇方法でこれをフォローアップします。

[[NSApplication sharedApplication] stopModal];

しかし、NSAlert の場合、beginSheetModalForWindow の「ウィンドウ」は、アラートがシートとして添付されるウィンドウを指し、そのウィンドウはアラートが無視されるまで凍結されます。ただし、アプリは凍結されません。他のすべてのウィンドウは引き続き操作可能です。アラートをシートとして添付し、アプリの残りの部分 フリーズする場合は、beginSheet コードに従って runModal を簡単に呼び出し、次のように戻りコードを明示的に使用します。

[alert beginSheetModalForWindow:self.window 
                  modalDelegate:self didEndSelector:@selector(abandonmentAlertDidEnd:returnCode:contextInfo:) 
                    contextInfo:nil];
NSInteger returnCode = [alert runModal];
[self abandonmentAlertDidEnd:alert returnCode:returnCode contextInfo:nil];

(もちろん、クラスメソッドとして放棄AlertDidEnd:returnCode:contextInfo:コードを実装しているでしょう。)

または、アラートを中央のパネルとして実行する場合は、runModal を単独で呼び出します。

パネル モーダルを実行し、ユーザーが無効なエントリを送信した場合に警告を表示するとします。アラートを表示する前に stopModal を実行する必要があります — その後、なんらかの理由で runModalForWindow への別の呼び出しが正しく機能しません。このシナリオでは、モーダル セッションが必要です。

1) modalSession は複数のメソッドからアクセスできる必要があるため、コントローラ クラスに NSModalSession プロパティを追加します。

2) パネルを表示したら、beginModalSessionForWindow を呼び出して modalSession をインスタンス化します。

self.modalSession = [[NSApplication sharedApplication] beginModalSessionForWindow:self.panelForInput];

3) runModalSession を呼び出す while ループでこれをフォローアップし、その戻り値が NSRunContinuesResponse と等しくない場合に中断します。

while ([[NSApplication sharedApplication] runModalSession:self.modalSession] == NSRunContinuesResponse)
    continue;

ユーザーがパネルのボタンの 1 つをクリックすると、ループが中断され、アプリが解放されます。(パネルのテキスト フィールドに入力すると、モーダル セッションはそのまま残ります。)

4) ボタン処理で、ユーザーの入力が無効な場合、runModal でアラートを呼び出します。

5) アラート呼び出しのすぐ下、アラートが解除されたときに実行されるコードに、上記で使用したものと同じ while ループを配置します。パネルのモーダル セッションが再開されます。

6) パネルを閉じる処理では、有効な入力時またはキャンセル時に endModalSession を呼び出しますが、奇妙なことに、これでは十分ではありません。runModalForWindow を呼び出したことがない場合でも、stopModal も呼び出す必要があります。

[[NSApplication sharedApplication] endModalSession:self.modalSession];
[[NSApplication sharedApplication] stopModal];
[self.panelForInput close];
4

1 に答える 1

3

質問は答えです。私はそれを締めくくるためにこれを投稿しています。stackoverflow 形式をねじ曲げて申し訳ありません。

于 2011-06-15T15:57:59.717 に答える