Je rencontre des problèmes lors de l'implémentation de la fonctionnalité QuickLook
à partir d'une table dans un NSView
. La documentation limitée sur n'aide vraiment pas du tout. Après avoir lu les Apple Docs (qui sont fortement axés sur les générateurs et les plugins personnalisés), j'ai fini par regarder le QuickLookDownloader sample code. Ce code est basé sur une application basée sur un document, mais semble être la bonne méthode pour moi (après tout, c'est le code d'Apple et cela fonctionne dans leur projet).Consommateur QuickLook en tant que délégué d'un NSViewController
Dans ma mise en œuvre, je peux obtenir le QuickLook panel
pour apparaître très bien, et je peux le rejeter tout aussi facile. Toutefois, le panneau lui-même n'appelle jamais les méthodes de délégué à partir de NSViewController
. En conséquence, je ne parviens jamais à afficher des objets, juste le libellé "Aucun élément sélectionné". Et je suis perplexe.
J'ai essayé d'appeler un setDelegate
, mais me mis en garde contre une catastrophe imminente si je continue dans cette voie ...
[QL] QLError(): - [QLPreviewPanel setDelegate:] appelé alors que le panneau n'a pas contrôleur - Fixez ceci ou cela augmentera bientôt. Voir les commentaires dans QLPreviewPanel.h pour -acceptsPreviewPanelControl:/- beginPreviewPanelControl:/- endPreviewPanelControl :.
Et puis malheur se passe quand même avec un dealloc en essayant de répondre à une des méthodes de délégué.
Et oui, j'ai lu l'en-tête qui confirme que je devrais définir le délégué après avoir gagné le panneau (voir le code ci-dessous). Donc voici mon code, qui correspond à peu près à l'exemple de code à l'exception de a) où je reçois mes données (je l'obtiens d'un NSArrayController
) et le b) où je reçois mon article de prévisualisation (le mien vient directement à partir de mon modèle d'objet - ou devrait de toute façon)
@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;
}
la question semble être que le acceptsPreviewPanelControl
ne sera jamais appelé, de sorte que les délégués ne se habituer (ils sont certainement jamais appelé).
Je suis sûr que c'est une étape simple qui me manque, mais après avoir disséqué l'exemple de code et récuré sur les documents, je ne vois pas la réponse. Est-ce parce que tout cela provient d'un NSViewController (bien que je ne vois pas pourquoi cela devrait même entrer dans l'équation)?
Tous et tous l'aide très appréciée.
SOLUTION MISE À JOUR
Merci à l'observation de Peter, le correctif est un rapide. Ne détestez-vous pas quand le message d'erreur dans le débogueur signifie ce qu'il dit? :-)
Dans ma classe chargée MyViewController
j'ai simplement besoin d'ajouter trois lignes de code pour résoudre le problème.
// 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];
Travail effectué :-) Merci Peter.Pourquoi voudriez-vous qu'il vous envoie des messages de délégué si vous n'êtes pas (encore) son délégué?
Comme d'habitude Peter votre observation était l'erreur dans mes moyens. J'avais négligé la notion que le NSViewController avait besoin d'être ajouté à la chaîne du répondeur (contrairement à un contrôleur de fenêtre qui est automatiquement inclus). 3 lignes de code et le problème est réparé automagiquement! Merci. Nuits tardives. Vous savez comment ça se passe :-) – Hooligancat
Je voulais dire que vous avez observé l'erreur dans mes façons, pas votre observation est l'erreur! – Hooligancat