Sto riscontrando alcuni problemi nell'implementazione della funzionalità QuickLook
da una tabella in un NSView
. La documentazione limitata su QuickLook
in realtà non aiuta affatto.Utente QuickLook come delegato da un NSViewController
Dopo aver letto il numero Apple Docs (che è fortemente orientato verso generatori e plug-in personalizzati), ho finito con lo QuickLookDownloader sample code. Questo codice si basa su un'applicazione basata su documenti, ma sembra essere il metodo giusto per me (dopotutto è il codice di Apple e funziona nel loro progetto).
Nella mia implementazione posso ottenere il QuickLook panel
per presentarsi bene, e posso liquidarlo altrettanto facile. Tuttavia, il pannello stesso non chiama mai i metodi delegati dal mio NSViewController
. Di conseguenza non riesco nemmeno a visualizzare oggetti, solo la dicitura "Nessun elemento selezionato". E sono perplesso.
Ho provato a chiamare un setDelegate
, ma vengo avvertito imminente castigo se continuo questa strada ...
[QL] QLError(): - [QLPreviewPanel setDelegate:] chiamato mentre il pannello non ha controller - Risolvi questo o questo aumenterà presto. Vedere i commenti in QLPreviewPanel.h per -acceptsPreviewPanelControl:/- beginPreviewPanelControl:/- endPreviewPanelControl :.
E quindi il doom si verifica comunque con un dealloc quando si tenta di rispondere a uno dei metodi delegati.
E sì, ho letto l'intestazione che conferma che dovrei impostare il delegato dopo aver vinto il pannello (vedi codice sotto).
Quindi ecco il mio codice, che praticamente corrisponde al codice di esempio con l'eccezione di a) da cui ottengo i miei dati (l'ho preso da un NSArrayController
) e il b) da cui ottengo il mio elemento di anteprima (il mio viene direttamente dal mio modello oggetto - o dovrebbe comunque)
@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;
}
il problema sembra essere che il acceptsPreviewPanelControl
mai viene chiamato, in modo che i delegati non si abitua (che sicuramente non vengono chiamati).
Sono sicuro che questo è un passaggio semplice che mi manca, ma dopo aver analizzato il codice di esempio e aver setacciato i documenti, non vedo la risposta.
È perché questo è tutto all'interno di un NSViewController (anche se non vedo alcuna ragione per cui dovrebbe entrare nell'equazione)?
Qualsiasi e tutti gli aiuti molto apprezzati.
soluzione di aggiornamento
Grazie all'osservazione di Peter, la correzione è stata una veloce. Non lo odi quando il messaggio di errore nel debugger indica cosa dice? :-)
Nella mia classe che ha caricato MyViewController
ho semplicemente dovuto aggiungere tre righe di codice per risolvere il problema.
// 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];
Lavoro svolto :-) Grazie Peter.
Come al solito Peter la tua osservazione è stata l'errore nei miei modi. Avevo trascurato il concetto che NSViewController ha bisogno di aggiungere nella catena di risposta (a differenza di un controller di finestra che viene automaticamente incluso). 3 righe di codice e il problema è risolto automagicamente! Grazie. Tarda notte. Sai come va :-) – Hooligancat
Intendo che hai osservato l'errore nei miei modi, non la tua osservazione è l'errore! – Hooligancat