调用beginSheet:completionHandler后如何等待工作表完成:

时间:2019-03-04 17:51:01

标签: xcode cocoa

我的代码导致工作表显示并正常工作,但是在工作表以endSheet结尾之前,调用者收到了控制权(根据Apple的定义)。

如何让调用者等待表单处理结束时返回,以便更新resultValue。

调用者:

[self.window beginSheet: sheetController.window
    completionHandler:^(NSModalResponse returnCode) {
        resultValue = returnCode;
    }
];
...

表格:

...
[self.window.sheetParent endSheet:self.window returnCode:false];

3 个答案:

答案 0 :(得分:0)

看起来您就在那里。返回码应为NSModalResponse(ObjC)或NSApplication.ModalResponse(Swift)。我还发现您需要取消选中“启动时可见”。否则,它将不会以模式启动。

Window options

答案 1 :(得分:0)

有一个NSAlert category from way back使用了较旧的(不推荐使用)方法。我对Objective-C并不太好(而对Swift则不好),但是一段时间以来,我一直在我的RubyMotion项目中使用等效的更新版本。希望我已经完成了反转代码转换的工作,但是基本上,它在调用runModalForWindow:之后使用beginSheetModalForWindow;触发了一个模式事件循环,并且completeHandler以stopModalWithCode:退出

// NSAlert+SynchronousSheet.h

#import <Cocoa/Cocoa.h>

/* A category to allow NSAlerts to be run synchronously as sheets. */
@interface NSAlert (SynchronousSheet)

/* Runs the receiver modally as a sheet attached to the specified window.
   Returns a value positionally identifying the button clicked */
-(NSInteger) runModalSheetForWindow:(NSWindow *)aWindow;

/* Same as above, but runs the receiver modally as a sheet attached to the
   main window. */
-(NSInteger) runModalSheet;

@end


// NSAlert+SynchronousSheet.m

#import "NSAlert+SynchronousSheet.h"

@implementation NSAlert (SynchronousSheet)

-(NSInteger) runModalSheetForWindow:(NSWindow *)theWindow {
    // Bring up the sheet and wait until it completes.
    [self beginSheetModalForWindow:theWindow
                 completionHandler:^(NSModalResponse returnCode) {
        // Get the button pressed - see NSAlert's Button Return Values.
        [NSApp stopModalWithCode:returnCode];
    }];
    [NSApp runModalForWindow:self.window]  // fire up the event loop
}

-(NSInteger) runModalSheet {
    return [self runModalSheetForWindow:[NSApp mainWindow]];
}

@end

应用程序将等待警报完成,然后再继续,并在结果中传递模式响应。我不知道要阻塞几千行代码,但是当链接两到三张纸时,例如在打开/保存面板之前发出警报时,我发现它很有用。

答案 2 :(得分:0)

我认为新的beginSheet:是用来完成整个链接的,但事实并非如此。它所做的全部都放在工作表窗口中。控制权的通过和返回保持原样。因此,以下代码有效:

调用者:

[self.window beginSheet: sheetController.window
    completionHandler:nil
];
returnCodeValue = [NSApp runModalForWindow:sheetController.window];
    // Sheet is active until stopModalWithCode issued.
[NSApp endSheet: sheetController.window];
[sheetController.window orderOut:self];

表格:

[NSApp stopModalWithCode:whatever];