当我像这样显示一个NSAlert时,我立即得到了响应:
int response;
NSAlert *alert = [NSAlert alertWithMessageText:... ...];
response = [alert runModal];问题是这是应用程序模式的,而我的应用程序是基于文档的。我使用工作表在当前文档的窗口中显示警报,如下所示:
int response;
NSAlert *alert = [NSAlert alertWithMessageText:... ...];
[alert beginSheetModalForWindow:aWindow
modalDelegate:self
didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
contextInfo:&response];
//elsewhere
- (void) alertDidEnd:(NSAlert *) alert returnCode:(int) returnCode contextInfo:(int *) contextInfo
{
*contextInfo = returnCode;
}这样做的唯一问题是beginSheetModalForWindow:会立即返回,所以我不能可靠地向用户提问并等待响应。如果我可以将任务分成两个区域,这不是什么大问题,但我不能。
我有一个循环,它处理大约40个不同的对象(在树中)。如果一个对象失败,我希望警报显示并询问用户是继续还是中止(在当前分支继续处理),但是由于我的应用程序是基于文档的,Apple Human Interface指南规定当警报特定于文档时使用工作表。
如何显示警告表并等待响应?
发布于 2009-03-03 02:29:21
不幸的是,您在这里可以做的并不多。基本上,您必须做出决定:重新设计您的应用程序,使其能够以异步方式处理对象,或者使用未经批准的、废弃的体系结构来呈现应用程序模式警报。
如果不知道有关实际设计和如何处理这些对象的任何信息,就很难提供任何进一步的信息。然而,在我的脑海中,可能会有几个想法:
然而,对于你需要的东西来说,这可能真的太复杂了。在这种情况下,我的建议是只使用不推荐使用的用法,但这实际上取决于您的用户需求。
发布于 2011-06-11 00:31:36
我们创建了一个category on NSAlert to run alerts synchronously,就像应用程序模式对话框一样:
NSInteger result;
// Run the alert as a sheet on the main window
result = [alert runModalSheet];
// Run the alert as a sheet on some other window
result = [alert runModalSheetForWindow:window];代码可以通过GitHub获得,为了完整起见,下面发布了当前版本。
头文件NSAlert+SynchronousSheet.h
#import <Cocoa/Cocoa.h>
@interface NSAlert (SynchronousSheet)
-(NSInteger) runModalSheetForWindow:(NSWindow *)aWindow;
-(NSInteger) runModalSheet;
@end实现文件NSAlert+SynchronousSheet.m
#import "NSAlert+SynchronousSheet.h"
// Private methods -- use prefixes to avoid collisions with Apple's methods
@interface NSAlert ()
-(IBAction) BE_stopSynchronousSheet:(id)sender; // hide sheet & stop modal
-(void) BE_beginSheetModalForWindow:(NSWindow *)aWindow;
@end
@implementation NSAlert (SynchronousSheet)
-(NSInteger) runModalSheetForWindow:(NSWindow *)aWindow {
// Set ourselves as the target for button clicks
for (NSButton *button in [self buttons]) {
[button setTarget:self];
[button setAction:@selector(BE_stopSynchronousSheet:)];
}
// Bring up the sheet and wait until stopSynchronousSheet is triggered by a button click
[self performSelectorOnMainThread:@selector(BE_beginSheetModalForWindow:) withObject:aWindow waitUntilDone:YES];
NSInteger modalCode = [NSApp runModalForWindow:[self window]];
// This is called only after stopSynchronousSheet is called (that is,
// one of the buttons is clicked)
[NSApp performSelectorOnMainThread:@selector(endSheet:) withObject:[self window] waitUntilDone:YES];
// Remove the sheet from the screen
[[self window] performSelectorOnMainThread:@selector(orderOut:) withObject:self waitUntilDone:YES];
return modalCode;
}
-(NSInteger) runModalSheet {
return [self runModalSheetForWindow:[NSApp mainWindow]];
}
#pragma mark Private methods
-(IBAction) BE_stopSynchronousSheet:(id)sender {
// See which of the buttons was clicked
NSUInteger clickedButtonIndex = [[self buttons] indexOfObject:sender];
// Be consistent with Apple's documentation (see NSAlert's addButtonWithTitle) so that
// the fourth button is numbered NSAlertThirdButtonReturn + 1, and so on
NSInteger modalCode = 0;
if (clickedButtonIndex == NSAlertFirstButtonReturn)
modalCode = NSAlertFirstButtonReturn;
else if (clickedButtonIndex == NSAlertSecondButtonReturn)
modalCode = NSAlertSecondButtonReturn;
else if (clickedButtonIndex == NSAlertThirdButtonReturn)
modalCode = NSAlertThirdButtonReturn;
else
modalCode = NSAlertThirdButtonReturn + (clickedButtonIndex - 2);
[NSApp stopModalWithCode:modalCode];
}
-(void) BE_beginSheetModalForWindow:(NSWindow *)aWindow {
[self beginSheetModalForWindow:aWindow modalDelegate:nil didEndSelector:nil contextInfo:nil];
}
@end发布于 2014-05-21 18:54:15
这里有一个NSAlert类别可以解决这个问题(正如Philipp建议的由Frederick提出的解决方案,并由Laurent P.改进:我使用代码块而不是委托,因此它再次被简化)。
@implementation NSAlert (Cat)
-(NSInteger) runModalSheetForWindow:(NSWindow *)aWindow
{
[self beginSheetModalForWindow:aWindow completionHandler:^(NSModalResponse returnCode)
{ [NSApp stopModalWithCode:returnCode]; } ];
NSInteger modalCode = [NSApp runModalForWindow:[self window]];
return modalCode;
}
-(NSInteger) runModalSheet {
return [self runModalSheetForWindow:[NSApp mainWindow]];
}
@endhttps://stackoverflow.com/questions/604768
复制相似问题