3

メニューバーのポップアップにNSTableViewを挿入しています。

テーブルビューとその内容に合わせて、ポップアップのパネルのサイズを変更したいと思います。たとえば、行がない場合、tableviewは非表示になります。新しい行を追加して、現在のテーブルビューの高さ+新しいセルの高さに基づいてパネルの高さを再計算しています。

セルを追加しています

[self.tableView insertRowsAtIndexes:[NSIndexSet indexSetWithIndex:0] withAnimation:NSTableViewAnimationSlideDown];

パネルの高さを次のように更新します。

[[self window] setFrame:panelRect display:YES animate:YES];

(すべて同じaddRowメソッド内)

これは正常に機能していますが、見た目は醜いです。テーブルビューとウィンドウは互いに別々にアニメーション化されています。私が欲しいのは、それらを同期し、テーブルビューの拡大と縮小と同時にウィンドウの境界線を移動することです。

iOSの開発経験に基づいて、tableviewのcontentSizeを観察するというアイデアがありましたが、そのアプローチに失敗しました。

- (void)awakeFromNib
{
    [super awakeFromNib];
    ...
    [self.scrollView.documentView addObserver:self forKeyPath:@"bounds.size" options:NSKeyValueObservingOptionNew context:NULL];
}

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

self.scrollviewIBのtableviewのコンテナscrollviewにリンクされています。そのコードは例外につながります:

An instance 0x10053a1d0 of class NSConcreteValue was deallocated while key value observers were still registered with it. Observation info was leaked, and may even become mistakenly attached to some other object. Set a breakpoint on NSKVODeallocateBreak to stop here in the debugger. Here's the current observation info:
<NSKeyValueObservationInfo 0x10053c850> (
<NSKeyValueObservance 0x10053c7a0: Observer: 0x10053a160, Key path: size, Options: <New: YES, Old: NO, Prior: NO> Context: 0x0, Property: 0x10053c880>
)

frame.sizeキーパスを使用すると、同じ例外が発生します。を使用するとframe、コールバックは返されません。

KVOでエラーが発生したり、ウィンドウのサイズ変更機能を使用してテーブルビューを実装するという別のアイデアが発生したりする可能性があります。

4

2 に答える 2

3

アニメーションの問題を解決できない場合があります。ただし、オブジェクトの割り当てが解除される前に、オブジェクトからオブザーバーを削除する必要があります。それは例外をなくします。つまり、この場合は

[self.scrollView.documentView removeObserver:self forKeyPath:@"bounds.size"];

[self.scrollView.documentView removeObserver:self forKeyPath:@"frame"]

これは、self.scrollView.documentView がメモリ不足になる前に実行する必要があります。それはトリッキーになる可能性があることを考慮して、次のようにオブザーバーを追加してみてください。

[self addObserver:self forKeyPath:@"self.scrollView.documentView.bounds.size" options:NSKeyValueObservingOptionNew context:Nil];

[self addObserver:self forKeyPath:@"self.scrollView.documentView.frame" options:NSKeyValueObservingOptionNew context:Nil];

別のことですが、どこかで読んだことを覚えていますが、フレームまたは境界を観察することは、一般的に良いアイデアとは見なされませんが、これについてはわかりません。

編集: 他の回答を考慮する: " " は、セッター メソッドを使用して直接設定されていないbounds.sizeため、機能しません。size代わりに、フレームを観察して、そこからサイズ情報を抽出します。(UIViewの場合、フレームのみが観察可能であり、境界ではありません。NSViewにも同じことが当てはまると思います)

于 2013-03-06T08:17:47.513 に答える
2
  1. 境界とフレームは C 型の構造体であり、オブジェクトではありません。
  2. Cocoa は境界とフレームを NSValue で自動的にラップしますが、NSRect は NSSize をラップしません。
  3. 変更通知は setXXX 関数によってトリガーされます。ボタンを追加して、次のようにアクションを記述してみてください。

    [self.scrollView.documentView setBounds:NSMakeRect(0, 0, 100, 100)];

于 2013-03-06T08:01:08.157 に答える