1

NSBezierPath 上のポイントから始まる NSView で NSPopover を表示しています。問題なくポップオーバーを表示できますが、2 つのテキスト フィールドの文字列値を設定できないようです。ポップオーバーとコンテンツ ビューは、それぞれ 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 が に設定された Object も設定されていますFile's Owner

私がどこで間違っているのかは、NSPopover のクラス/インスタンス変数をどのように構成したかに関連している可能性が高いと思いますが、私が行った調査と読んだドキュメントから、どこに行ったのかクラックできないようです違う。どんな助けでも大歓迎です。

アップデート:

NSPopover サブクラスをコードと IB から削除しました。アウトレットを NSViewController に配置し、それらを IB に接続しました。ただし、文字列値を設定することはまだできません。以下は、「Property 'weightLabel' not found on object of type 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 のサブクラスを介して設定する必要があると考えました。これが、クラス/インスタンス変数の構成方法に問題があると思った理由です。

4

2 に答える 2

0

私も似たようなことを経験したことがあります。根本的な問題は、ビュー (XIB) をコントローラーに接続する「アウトレット」が、ビューが表示されるまで初期化されないことです。ポップオーバーが開かれる前にコントローラーがビュー内の UI コントロールのプロパティを設定しようとすると、それらの変更は無視されます (すべてのコントロールが nil になるため)。

幸いなことに、簡単な解決策があります (この回答で述べたようにview):コントローラーでゲッターを呼び出すだけで、ビューがより早く初期化されます。

言い換えると:

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 に答える
0

1 つはコード ( popover = [[WeightPopoverController alloc] init]) で、もう 1 つは Interface Builder で 2 つのポップオーバーを作成しているようです (この xib では、オブジェクトを WeightPopoverController に設定しています)。あなたが達成しようとしていることについて考えてみてください。

また、サブクラス化しないことをお勧めしNSPopoverます。これは混乱を招いており、不必要だと思います。代わりに、ポップオーバーのコンテンツ ビュー コントローラーにアウトレットを配置しdateLabelますweightLabel

于 2014-09-12T15:40:37.390 に答える