2010-11-01 65 views
4

我的目標是:在應用程序通過冗長的循環工作時顯示帶有確定NSProgressIndicator的自定義表單。我希望工作表是應用程序模式的,而不是文檔模式的。用戶不能解除模態表單。他們必須等待應用程序完成循環處理。使用Cocoa自定義模態表時遇到問題

問題:我無法將自定義工作表添加到窗口中。它顯示爲一個單獨的窗口,缺少窗口標題欄(如表單所示)。另外,當循環結束時,表格不會被釋放(不關閉)。

我有2個獨立的筆尖和主應用程序窗口的nib文件,還有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嗎?預先感謝您的幫助!

回答

15

找到this gem做一些Google搜索。 Interface Builder中我的NSPanel的行爲被設置爲「在啓動時可見」,這是使用IB時新窗口的默認值。發生了什麼事情,只要裝入筆尖,窗口就會在​​之前顯示出來。因此,取消選中「啓動時顯示Visible」選項解決了我的問題,現在一張表單連接到窗口就像我想要的那樣。

1
@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是錯誤的類型。對於NSArray索引,您應該使用NSUInteger

其次,除非你需要索引別的東西,你應該使用fast enumeration

+0

彼得,感謝您的快速枚舉提示。我用「for(NSURL * fileURL in filesToTest)」替換了「for」語句,因爲這就是數組包含的內容。 「[NSApp mainWindow]」不是零。我用NSLogs代碼來查找。它通過了正確的窗口。我不確定是否正確使用模態會話。 「beginModalSessionforWindow:」返回NSModalSession。我把它變成了伊娃,這樣我的「removeProgressSheet:」方法就可以結束模態會話。但是,即使我刪除模態會話代碼,我仍然有同樣的問題。嗯... – 2010-11-02 16:27:45

相關問題