2010-10-01 32 views
9

我在NSView的表中執行QuickLook功能時出現問題。 QuickLook上的有限文檔確實沒有任何幫助。QuickLook使用者作爲NSViewController的委託

通過Apple Docs(它們主要面向自定義生成器和插件)閱讀後,我終於看到QuickLookDownloader sample code。此代碼基於基於文檔的應用程序,但似乎對我來說是正確的方法(畢竟它是Apple的代碼,並且它在他們的項目中工作)。

在我的實現中,我可以讓QuickLook panel顯示得很好,我可以輕鬆地解除它。但是,面板本身從不會調用我的NSViewController中的委託方法。因此,我甚至從來沒有去顯示對象,只是措辭「沒有選擇項目」。我很難過。

我試圖調用setDelegate,但得到警告即將到來的厄運,如果我繼續沿着路線......

[QL] QLError(): - [QLPreviewPanel setDelegate:]叫,而面板上沒有控制器 - 解決這個問題,否則這個問題會很快提升 請參閱QLPreviewPanel.h中關於-acceptsPreviewPanelControl的註釋:/ - beginPreviewPanelControl:/ - endPreviewPanelControl :.

然後當試圖響應某個委託方法時,無論如何都會發生dealloc。

是的,我確實讀過頭文件,確認我在贏得面板後應該設置代表(請參閱下面的代碼)。

所以這裏是我的代碼,它幾乎與示例代碼相匹配,但a)從哪裏獲得我的數據(我從NSArrayController獲取數據)和b)從哪裏獲取預覽項目直接從我的模型對象 - 或者應該這樣)

@interface MyViewController : NSViewController 
    <QLPreviewPanelDataSource, QLPreviewPanelDelegate> { 

    QLPreviewPanel * previewPanel; 
    NSArrayController * myArrayController; 
    NSTableView * myTable; 

    // [...] Other instance vars 
} 

@implementation MyViewController 

// [...] all the other methods, init, dealloc etc... 

-(IBAction)togglePreviewPanel:(id)previewPanel { 

    if ([QLPreviewPanel sharedPreviewPanelExists] && 
      [[QLPreviewPanel sharedPreviewPanel] isVisible]) 
    { 
     [[QLPreviewPanel sharedPreviewPanel] orderOut:nil]; 
    } 
    else 
    { 
     [[QLPreviewPanel sharedPreviewPanel] makeKeyAndOrderFront:nil]; 
    } 
} 

-(BOOL)acceptsPreviewPanelControl:(QLPreviewPanel *)panel 
{  
     return YES; 
} 

// This document is now responsible of the preview panel. 
// It is allowed to set the delegate, data source and refresh panel. 

-(void)beginPreviewPanelControl:(QLPreviewPanel *)panel 
{ 

    if (DEBUG) NSLog(@"QuickLook panel control did BEGIN"); 

    previewPanel = [panel retain]; 
    panel.delegate = self; 
    panel.dataSource = self; 
} 

// This document loses its responsisibility on the preview panel. 
// Until the next call to -beginPreviewPanelControl: it must not change 
// the panel's delegate, data source or refresh it. 

-(void)endPreviewPanelControl:(QLPreviewPanel *)panel 
{ 
    [previewPanel release]; 
    previewPanel = nil; 

    if (DEBUG) NSLog(@"QuickLook panel control did END"); 
} 

// Quick Look panel data source 

-(NSInteger)numberOfPreviewItemsInPreviewPanel:(QLPreviewPanel *)panel 
{ 

    if (DEBUG) NSLog(@"QuickLook preview count called"); 

    return [[myArrayController selectedObjects] count]; 
} 

-(id <QLPreviewItem>)previewPanel:(QLPreviewPanel *)panel 
     previewItemAtIndex:(NSInteger)index 
{ 

    if (DEBUG) NSLog(@"QuickLook preview selection of item called"); 

    return [[displayAC selectedObjects] objectAtIndex:index]; 
} 

-(BOOL)previewPanel:(QLPreviewPanel *)panel handleEvent:(NSEvent *)event { 

    if (DEBUG) NSLog(@"QuickLook panel error handler called"); 

// redirect all key down events to the table view 

    if ([event type] == NSKeyDown) { 
     [myTable keyDown:event]; 
    return YES; 
    } 

    return NO; 
} 

這個問題似乎是在acceptsPreviewPanelControl不會被調用,所以代表們從來沒有習慣(他們肯定永遠不會調用)。

我敢肯定,這是一個簡單的步驟,我失蹤了,但在解剖示例代碼和搜索文檔後,我沒有看到答案。

是因爲這全部來自NSViewController內部(儘管我沒有看到爲什麼它應該進入方程式)?

任何和所有的幫助非常感謝。

解決方案Update

感謝彼得的觀察,修復是一個快速。當調試器中的錯誤信息意味着它說什麼時,你不討厭它嗎? :-)

在我的班加載MyViewController我只需要添加三行代碼來解決這個問題。

// mainWindow is an IBOutlet to my window because the calling class 
// is a simple object and not an NSWindowController otherwise I could 
// have used `self` instead of `mainWindow` 

NSResponder * aNextResponder = [mainWindow nextResponder]; 

[mainWindow setNextResponder:myViewControllerInstance]; 
[myViewControllerInstance setNextResponder:aNextResponder]; 

工作完成:-)謝謝彼得。

回答

6

如果你不是它的代表,你爲什麼期望它能發送給你委託消息?如果您希望它向您發送委託消息,則需要將自己設置爲其委託。

我試圖調用setDelegate,但得到警告即將到來的厄運,如果我繼續沿着路線......

[QL] QLError()-[QLPreviewPanel setDelegate:]稱爲同時面板上沒有操控 - 修復此或這將很快提升。請參閱QLPreviewPanel.h中的註釋-acceptsPreviewPanelControl:/-beginPreviewPanelControl:/-endPreviewPanelControl:

「沒有控制器」,它說。所以,你需要它有一個控制器。

關於該標題的註釋,特別是acceptsPreviewPanelControl:和QLPreviewPanel實例方法updateController,建議面板的控制器(當它有一個時)是響應器鏈中的一個對象。因此,如果您的控制器不是控制器的控制器,那是因爲您的控制器不在響應器鏈中。

所以,解決這個問題,然後它就會起作用。

我會想象你的視圖控制器應該在響應鏈中,只要它的視圖或其子視圖在響應鏈中,但可能情況並非如此。 The documentation不說。如果一切都失敗了,請將自己明確地設置爲某個視圖的下一個響應者(並將其先前的下一個響應者作爲下一個響應者),然後向預覽面板發送一條updateController消息。

+0

像往常一樣彼得你的觀察是我的方式錯誤。我忽略了NSViewController需要添加到響應者鏈中的想法(與自動獲取的窗口控制器不同)。 3行代碼,問題自動修復!謝謝。深夜。你知道它是怎麼回事:-) – Hooligancat 2010-10-01 23:10:30

+0

我的意思是你在我的方式觀察錯誤,而不是你的觀察是錯誤! – Hooligancat 2010-10-01 23:24:13