Проблемы с использованием пользовательских модальных листов с какао - PullRequest
4 голосов
/ 01 ноября 2010

Моя цель: отобразить пользовательский лист с определенным NSProgressIndicator, пока приложение работает через длинный цикл. Я хочу, чтобы лист был модальным приложения, а не документальным. Пользователь не может отклонить модальный лист. Они должны ждать, пока приложение завершит обработку цикла.

Проблема: я не могу прикрепить пользовательский лист к окну. Это выглядит как отдельное окно без строки заголовка окна (как лист должен). Кроме того, лист не освобождается (не закрывается), когда цикл заканчивается.

У меня есть 2 отдельных файла пера для листа и основного окна приложения, а также 2 класса контроллера для каждого окна.

Вот соответствующая информация: Реализация контроллера для пользовательского листа:

@implementation ProgressSheetController //subclass of NSPanel

-(void)showProgressSheet:(NSWindow *)window
{
    //progressPanel is an IBOutlet to the NSPanel
    if(!progressPanel)
        [NSBundle loadNibNamed:@"ProgressPanel" owner:self];

    [NSApp beginSheet: progressPanel
       modalForWindow: window
        modalDelegate: nil
       didEndSelector: nil
          contextInfo: nil];

    //modalSession is an instance variable
    modalSession = [NSApp beginModalSessionForWindow:progressPanel];

    [NSApp runModalSession:modalSession];
}

-(void)removeProgressSheet
{
    [NSApp endModalSession:modalSession];
    [NSApp endSheet:progressPanel];
    [progressPanel orderOut:nil];
}

//some other methods 
@end

Реализация для основного окна приложения. Метод testFiles - это IBAction, подключенный к кнопке.

@implementation MainWindowViewController //subclass of NSObject

-(IBAction)testFiles:(id)sender;
{
    //filesToTest is a mutable array instance variable
    int count = [filesToTest count];

    float progressIncrement = 100.0 / count;

    ProgressSheetController *modalProgressSheet = [[ProgressSheetController alloc] init];
    [modalProgressSheet showProgressSheet:[NSApp mainWindow]];

    int i,
    for(i=0; i<count; i++)
    {
        //do some stuff with the object at index i in the filesToTest array

        //this method I didn't show in ProgressSheetController.m but I think it's self explanatory
        [modalProgressSheet incrementProgressBarBy:progressIncrement];
    }
    //tear down the custom progress sheet
    [modalProgressSheet removeProgressSheet];
    [modalProgressSheet release];
}
@end

Одна мысль: правильно ли я делаю подклассы? Должен ли я использовать NSWindowController вместо этого? Заранее благодарю за помощь!

Ответы [ 2 ]

15 голосов
/ 03 ноября 2010

Найден этот камень занимается поиском. Поведение для моего NSPanel в Интерфейсном Разработчике было установлено в «Видимый при запуске», который является значением по умолчанию для новых окон при использовании IB. То, что произошло, было, как только перо было загружено, окно стало видимым ДО [NSApp beginSheet:...]. Поэтому снятие флажка «Видимый при запуске» решило мою проблему, и теперь появляется окно, подключенное к окну, как я хочу.

1 голос
/ 01 ноября 2010
@implementation ProgressSheetController //subclass of NSPanel

-(void)showProgressSheet:(NSWindow *)window
{
    //progressPanel is an IBOutlet to the NSPanel
    if(!progressPanel)
        [NSBundle loadNibNamed:@"ProgressPanel" owner:self];

То есть вашему NSPanel принадлежит еще один NSPanel? Если вторая панель прогресса, что показывает первая?

Должен ли я вместо этого [подкласс] NSWindowController?

Звучит так.

modalSession = [NSApp beginModalSessionForWindow:progressPanel];

Почему?

[modalProgressSheet showProgressSheet:[NSApp mainWindow]];

Вы убедились, что есть главное окно? mainWindow не возвращает окно, которое вам больше всего нужно; возвращает активное окно (которое, вероятно, но не обязательно, также является ключевым).

Если mainWindow возвращает nil, это может быть причиной вашей проблемы.

int i,
for(i=0; i<count; i++)
{
    //do some stuff with the object at index i in the filesToTest array

Во-первых, int - неправильный тип. Вы должны использовать NSUInteger для индексов NSArray.

Во-вторых, если вам не нужен индекс для чего-то другого, вы должны использовать быстрое перечисление .

...