2

背景:印刷ダイアログに印刷パネルアクセサリビューを追加しています(を使用addAccessoryController:)。コントロールはNSPrintInfo printSettings値にバインドされているため、値は印刷プリセットに保存されます。printSettingsの変更を監視するのに問題があります。SDK 10.6でビルドし、OSX10.7でテストしています。

これは私の理解では機能するはずのコードサンプルですが、observeValueForKeyPath:呼び出されることはありません。

- (void)testKVO
{
  NSPrintInfo *printInfo = [NSPrintInfo sharedPrintInfo];
  [printInfo addObserver:self forKeyPath:@"printSettings.foo" options:0 context:NULL];
  [printInfo setValue:@"bar" forKeyPath:@"printSettings.foo"]; // observeValueForKeyPath:ofObject:change:context: not called
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
  NSLog(@"%s %@ :: %@", _cmd, keyPath, object);
}

また、printSettingsを直接監視しようとしましたが、成功しませんでした。observerメソッドも呼び出されません(NSPrintInfoによって返されるprintSettingsは実際にはクラスですNSPrintInfoDictionaryProxy)。

- (void)testKVO
{
  NSMutableDictionary *printSettings = [[NSPrintInfo sharedPrintInfo] printSettings];
  [printSettings addObserver:self forKeyPath:@"foo" options:0 context:NULL];
  [printSettings setValue:@"bar" forKey:@"foo"]; // observeValueForKeyPath:ofObject:change:context: not called
}

KVOシステムが通常の状態で動作することを再確認し、オブザーバーメソッドを呼び出します。

- (void)testKVO
{
  NSMutableDictionary *printSettings = [NSMutableDictionary dictionary];
  [printSettings addObserver:self forKeyPath:@"foo" options:0 context:NULL];
  [printSettings setValue:@"bar" forKey:@"foo"]; // observeValueForKeyPath:ofObject:change:context: called at last!
}

したがって、問題は、printSettingsの変更をどのように観察できるか、特にユーザーが印刷プリセットをいつ選択したかを知るためにどうすればよいかということです。

また、プレビューを次のように自動的に更新したいのですが

- (NSSet *)keyPathsForValuesAffectingPreview
{
  return [NSSet setWithObjects:
          @"representedObject.printSettings.foo",
          nil];
}

プレビューの更新には簡単な回避策があります。NSViewController自体でプロパティを直接再宣言することにより、間接レベルを追加します。しかし、印刷プリセットの変更については、私には手がかりがありません。

最後に、NSPrintInfo.hのコメントは次のとおりです。

- (NSMutableDictionary *)printSettings;

印刷情報の印刷設定。この辞書に値を入れて、ユーザーが印刷パネルでこの印刷情報を編集しているときに作成した任意のプリセットに値を保存できます。このような値は、プロパティリストオブジェクトである必要があります。このクラスは、「printSettings」に準拠したKey-Valueコーディング(KVC)およびKey-Value監視(KVO)であるため、多くの場合、印刷パネルのアクセサリビューのコントロールをこのディクショナリのエントリに直接バインドできます。このディクショナリを使用して、プリンタドライバの印刷ダイアログ拡張機能(Carbon Printing ManagerのPMPrintSettingsGetValue()関数によって返されるのと同じ種類の値)など、印刷システムの他の部分によって設定された値を取得することもできます。印刷システムの他の部分では、「com.apple.print.PrintSettings.PMColorSyncProfileID」などのキー文字列を使用することがよくあります。ただし、キー文字列にあるようなドットはKVCではうまく機能しないため、これらのドットは、「com_apple_print_PrintSettings_PMColorSyncProfileID」のように、この辞書に表示されるキーのアンダースコアに置き換えられます。このディクショナリにエントリを追加するときは、同じ規則を使用する必要があります。

助けていただければ幸いです

ありがとう

4

1 に答える 1

4

さて、私は方法を見つけました。印刷プリセットの選択時または用紙フォーマットの変更時に送信される文書化されていない通知があります。オブザーバーを追加するだけで済みます。

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(printInfoDidChange:) name:@"NSPrintInfoDidChange" object:nil];

これは、printSettings キーパスへのバインドほど簡単ではなく、文書化されていない通知を使用するのは本当に好きではありません (保守性の点でプライベート API を使用するのと同じくらい悪いです) が、それが仕事をするために理解できる唯一の方法です。

于 2012-06-28T11:46:25.667 に答える