警告パネルを表示して、ユーザからなにかしらの入力を待ち、それによってプログラムの振る舞いを変えたいことがある。例えば、ファイヤウォールのようなアプリケーションを作成して、あるサイトからのアクセスがあった場合に、そのサイトからのアクセスを許可するかどうかをユーザに訪ねる場合だ。
このとき、NSAlertではなく、NSWindowやNSPanelを拡張して自前のクラスを用意した場合に、ユーザの入力を待ちつつ自前クラスの処理を平行して行いたいのだが、どうやってユーザの入力を待つかがむずかしい。なぜならば、単純にwhileとsleepでまわすと、そのRunLoop内のすべての処理をblockしてしまうから。
解決方法は、そのクラスをmodalSessionにして、必要な処理はタイマで回す。その際、タイマは、NSModalPanelRunModeにも追加しておく。
(NSWindowを継承したクラス内)
--- init method
timer = [NSTimer timerWithTimeInterval:0.05 target:self selector:@selector(alertWindowAppear) userInfo:nil repeats: NO];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSModalPanelRunLoopMode];
--- modal method
NSModalSession session = [NSApp beginModalSessionForWindow:self];
int modalResult;
do {
modalResult = [NSApp runModalSession:session];
if (modalResult == NSOKButton) {
[NSApp abortModal];
[NSApp endModalSession:session];
// related processing here
} else if (modalResult == NSCancelButton) {
[NSApp abortModal];
[NSApp endModalSession:session];
// related processing here
}
} while (modalResult == NSRunContinuesResponse);
0 件のコメント:
コメントを投稿