Невозможно установить контент в NSPopover
Я показываю NSPopover в NSView, происходящий из точки на NSBezierPath. Я могу показать поповер без проблем, но я не могу установить строковое значение двух текстовых полей в нем. Всплывающее окно и представление контента являются пользовательским подклассом NSPopover и NSViewController соответственно. Подкласс NSPopover также является делегатом NSPopover, хотя я не использую методы делегатов, поэтому я не уверен, что мне даже нужно это делать.
Вот мой подкласс NSViewController:
#import <Cocoa/Cocoa.h>
@interface WeightPopoverViewController : NSViewController
@end
#import "WeightPopoverViewController.h"
@interface WeightPopoverViewController ()
@end
@implementation WeightPopoverViewController
- (id)init {
self = [super initWithNibName:@"WeightPopoverViewController" bundle:nil];
if (self) {
}
return self;
}
@end
И мой подкласс NSPopover:
#import <Cocoa/Cocoa.h>
@interface WeightPopoverController : NSPopover <NSPopoverDelegate> {
NSTextField *dateLabel;
NSTextField *weightLabel;
}
@property (strong) IBOutlet NSTextField *dateLabel;
@property (strong) IBOutlet NSTextField *weightLabel;
@end
#import "WeightPopoverController.h"
@implementation WeightPopoverController
@synthesize weightLabel;
@synthesize dateLabel;
@end
Это код в моем подклассе NSView, который открывает поповер:
@interface WeightGraphViewController () {
WeightPopoverController *popover;
WeightPopoverViewController *vc;
}
...
-(void)mouseEntered:(NSEvent *)theEvent {
// initialize the popover and its view controller
vc = [[WeightPopoverViewController alloc] init];
popover = [[WeightPopoverController alloc] init];
// configure popover
[popover setContentViewController:vc];
[popover setDelegate:popover];
[popover setAnimates:NO];
// set labels
for (id key in (id)[theEvent userData]) {
[popover.weightLabel setStringValue:[(NSDictionary*)[theEvent userData] objectForKey:key]];
[popover.dateLabel setStringValue:key];
}
// set the location
(redacted, irrelevant)
// show popover
[popover showRelativeToRect:rect ofView:[self window].contentView preferredEdge:NSMaxYEdge];
}
-(void)mouseExited:(NSEvent *)theEvent {
[popover close];
popover = nil;
}
В WeightPopoverViewController.xib
Я установил File's Owner
в WeightPopoverViewController
и подключил вид к пользовательскому NSView. В этом xib у меня также есть объект, установленный в WeightPopoverController
с dateLabel и weightLabel, подключенными к их текстовым полям, и contentViewController установлен в File's Owner
,
Я думаю, что то, что я делаю не так, вероятно, связано с тем, как я настроил переменные моего класса / экземпляра для NSPopover, но из проведенного мною исследования и прочитанной документации я не могу понять, куда я пошел неправильно. Любая помощь будет оценена.
ОБНОВИТЬ:
Я удалил подкласс NSPopover из кода и из IB. Я поместил свои розетки в мой NSViewController и соединил их в IB. Тем не менее, я до сих пор не могу установить строковые значения. Следующее не скомпилируется с ошибкой "Свойство weightLabel не найдено для объекта типа NSPopover*".
@interface WeightGraphViewController () {
NSPopover *popover;
...
}
-(void)mouseEntered:(NSEvent *)theEvent {
vc = [[WeightPopoverViewController alloc] init];
popover = [[NSPopover alloc] init];
[popover setContentViewController:vc];
[popover.dateLabel setStringValue:@"test"];
}
У меня есть определение свойства точно так же, как оно было в моем подклассе NSPopover, но теперь в моем NSViewController. Это на самом деле то, что у меня было раньше, и, поскольку я не смог установить свойства из NSViewController, я решил, что мне нужно сделать это через подкласс NSPopover. Вот почему у меня возникла проблема с настройкой переменных класса / экземпляра.
2 ответа
Вы, кажется, создаете два popovers, один в коде (popover = [[WeightPopoverController alloc] init]
) и один в Интерфейсном Разработчике (В этом xib у меня также есть Объект, установленный в WeightPopoverController). Подумайте о том, чего вы пытаетесь достичь.
Я бы также советовал против подклассов NSPopover
, Я считаю, что это вызывает путаницу и не является необходимым. Вместо этого поставьте розетки на ваш dateLabel
а также weightLabel
в контроллере представления контента поповера.
Я испытал нечто похожее. Основная проблема заключается в том, что "выходы", соединяющие ваше представление (XIB) с вашим контроллером, не инициализируются до тех пор, пока представление не будет отображено. Если контроллер пытается установить свойства для каких-либо элементов управления пользовательского интерфейса в представлении до открытия всплывающего окна, эти изменения игнорируются (поскольку все элементы управления будут нулевыми).
К счастью, есть простое решение ( как уже упоминалось в этом ответе): просто вызовите view
getter на вашем контроллере, и он заставит представление инициализироваться раньше.
Другими словами:
popover = [NSPopover new];
myController = [[MyViewController alloc] initWithNibName:@"MyView" bundle:nil];
popover.contentViewController = myController;
[myController view]; // force view to initialize
...set some values on myController... // works because view is now loaded
[popover showRelativeToRect: ...];