У меня возникли проблемы с реализацией функциональности QuickLook
из таблицы в NSView
. Ограниченная документация по QuickLook
действительно совсем не помогает.
Прочитав Apple Docs (которые в значительной степени ориентированы на пользовательские генераторы и плагины), я в итоге посмотрел пример кода QuickLookDownloader . Этот код основан на приложении на основе документов, но мне кажется, что он мне подходит (в конце концов, это код Apple, и он работает в их проекте).
В моей реализации я могу получить QuickLook panel
, который будет отображаться просто отлично, и я могу просто так отклонить его. Однако сама панель никогда не вызывает методы делегата из моего NSViewController
. В результате я даже не дохожу до отображения объектов, просто формулировка "Элементы не выбраны" . И я в тупике.
Я пытался дозвониться до setDelegate
, но меня предупредили о надвигающейся гибели, если я продолжу идти по этому маршруту ...
[QL] QLError (): - [QLPreviewPanel setDelegate:] вызывается, когда на панели нет контроллера - Исправьте это или это скоро повысится.
Смотрите комментарии в QLPreviewPanel.h для -acceptsPreviewPanelControl: / - beginPreviewPanelControl: / - endPreviewPanelControl:.
И затем в любом случае происходит doom с dealloc при попытке ответить на один из методов делегата.
И да, я прочитал заголовок, который подтверждает, что я должен назначить делегата после того, как выиграл панель (см. Код ниже).
Итак, вот мой код, который в значительной степени совпадает с примером кода, за исключением а) откуда я получаю свои данные (я получаю их из NSArrayController
) и б) откуда я получаю свой элемент предварительного просмотра (мой приходит прямо из моего модельного объекта - или должен в любом случае)
@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 (хотя я не вижу причин, почему это должно даже войти в уравнение)?
Любая помощь очень ценится.
ОБНОВЛЕНИЕ РЕШЕНИЯ
Благодаря наблюдению Питера, решение было быстрым. Разве вы не ненавидите, когда сообщение об ошибке в отладчике означает, что оно говорит? : -)
В моем классе, который загрузил 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];
Работа сделана :-) Спасибо, Питер.