gpt4 book ai didi

cocoa - 等待[NSAlert beginSheetModalForWindow :. ..];

转载 作者:行者123 更新时间:2023-12-03 16:01:52 31 4
gpt4 key购买 nike

当我显示这样的 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 人机界面指南规定在警报发生时使用工作表特定于文档。

如何显示警报表并等待响应?

最佳答案

我们创建了一个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

关于cocoa - 等待[NSAlert beginSheetModalForWindow :. ..];,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/604768/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com