Как дождаться завершения листа после вызова beginSheet: завершениюHandler: - PullRequest
0 голосов
/ 04 марта 2019

Мой код приводит к тому, что лист появляется и функционирует должным образом, но инициатор получает контроль обратно (согласно определению Apple) до того, как лист завершает себя с помощью endSheet.

Как я могу заставить инициатора ждать возвратас конца обработки листа, поэтому значение resultValue обновляется.

Invoker:

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

Sheet:

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

Ответы [ 3 ]

0 голосов
/ 05 марта 2019

С момента появления существовала категория NSAlert, в которой использовались более старые (устаревшие) методы.Я не так хорош в Objective-C (и хуже в Swift), но некоторое время я использовал обновленный эквивалент в одном из моих проектов RubyMotion.Надеюсь, я подошел ближе к обратному преобразованию кода, но в основном он запускает цикл модальных событий с runModalForWindow: после вызова beginSheetModalForWindow;, и завершениеHandler завершается с 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

Приложениебудет ожидать завершения оповещения, прежде чем продолжить, с модальным ответом, переданным в результате.Я не знаю о блокировке нескольких тысяч строк кода, но я нашел это полезным при объединении в цепочку двух или трех листов, таких как предупреждение перед панелью открытия / сохранения.

0 голосов
/ 05 марта 2019

Я думал, что новый beginSheet: должен был выполнить всю связь, но это не так.Все, что он делает, это поднимает окно листа.Прохождение и возврат контроля остаются прежними.Так работает следующий код:

Invoker:

[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];
0 голосов
/ 05 марта 2019

Похоже, ты там почти весь путь.Код возврата должен иметь тип NSModalResponse (ObjC) или NSApplication.ModalResponse (Swift).Я также обнаружил, что вам нужно снять флажок «Видимо при запуске».В противном случае он не будет запускаться как модальный.

Window options

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...