无法在NSPopover中设置内容

时间:2014-09-12 13:50:59

标签: objective-c cocoa nsviewcontroller nspopover

我在NSView中显示NSPopover,源自NSBezierPath上的一个点。我能够毫无问题地显示弹出窗口,但我似乎无法设置其中两个文本字段的字符串值。 popover和content视图分别是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子类中打开popover的代码:

@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中,我还有一个Object设置为WeightPopoverController,其中dateLabel和weightLabel连接到它们的文本字段,contentViewController设置为File's Owner

我认为我出错的地方很可能与我如何为NSPopover配置我的类/实例变量有关,但是从我已经完成的研究和文档中我已经阅读过我似乎无法破解我在哪里出了问题。任何帮助,将不胜感激。

更新

我从代码和IB中删除了NSPopover子类。我将我的插座放在我的NSViewController中并将它们连接到IB中。但是,我仍然无法设置字符串值。以下将无法编译错误“NSPopover *'对象上找不到”属性'weightLabel'。“

@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 个答案:

答案 0 :(得分:0)

您似乎正在创建两个弹出框,一个在代码中(popover = [[WeightPopoverController alloc] init]),一个在Interface Builder中(在此xib中我也有一个Object设置为WeightPopoverController )。想一想你想要实现的目标。

我还建议不要继承NSPopover。我相信这会造成混乱,而且是不必要的。而是将出口放在popover的内容视图控制器中的dateLabelweightLabel

答案 1 :(得分:0)

我经历过一些我认为相似的事情。根本问题是&#34;出口&#34;将视图(XIB)连接到控制器不会初始化,直到显示视图后。如果控制器在打开弹出窗口之前尝试在视图中的任何UI控件上设置属性,则会忽略这些更改(因为所有控件都将为nil)。

幸运的是,这是一个简单的解决方案(as mentioned in this answer):只需调用控制器上的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: ...];