1

我在 NSView 中显示了一个 NSPopover,它源自 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 OwnerWeightPopoverViewController并将视图连接到自定义 NSView。在这个 xib 中,我还设置了一个对象,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 的子类来完成。这就是为什么我认为我在配置类/实例变量方面存在问题。

4

2 回答 2

0

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

我也建议不要子类化NSPopover。我认为这会造成混乱并且是不必要的。相反,将插座放在您的dateLabelweightLabel弹出框的内容视图控制器中。

于 2014-09-12T15:40:37.390 回答
0

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

幸运的是,有一个简单的解决方案(如本答案中所述):只需调用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: ...];
于 2016-03-22T04:58:02.800 回答