1

NSOutlineViewコア データ ストアからのエントリ (ソース エンティティ) を表示するビュー ベースがあります。アウトライン ビューのビューは、 のサブクラスとして実装されるカスタム コントロールを使用しますNSView。このコントロールは、数値 (0 ~ 7) に基づいて色付きの丸いマーカーを表示します。この値は、Source エンティティの属性として格納され、Finder に似たラベル付け方法を実装する方法として意図されています。

全体が IB のバインディングを使用して配線されています。

私の意図が明確になることを願って、スクリーンショットを添付しました。

それはすべてうまく機能しますが、本当に厄介な詳細が1つあります. 数値が (画面の右側から) 変更された場合、カスタム コントロールは、アウトライン ビューでの選択が変更された場合にのみ更新されます。明らかに、この変更がすぐに反映される方が良いでしょうが、これまでのところ失敗しています。setNeedsDisplay: YES基本的にすべて無視されたさまざまなシナリオを試しました。

何か案は?

ここに画像の説明を入力

編集:カスタムコントロールでセッターを実装しました:

- (void) setLabelValue: (NSNumber*) aValue {
    labelValue = aValue;
    [self setNeedsDisplay: YES];
}

setNeedsDisplay:が再描画をトリガーするという理由で、メソッドdrawRect:で値を照会して適切な色を確立します。

- (void)drawRect: (NSRect) dirtyRect {
    // Label value between '1' and '7' indicate that a label was assigned. Determine label color and border color.
    if ([[self labelValue] intValue] > 0) {
        NSColor *aBackgroundColor = [NSColor clearColor];
        switch ([[self labelValue] intValue]) {
            case 1:
                aBackgroundColor = [NSColor colorWithCalibratedRed:...];
                break;
            case 2:
                aBackgroundColor = [NSColor colorWithCalibratedRed:...];        
                break;
            case 3:
                aBackgroundColor = [NSColor colorWithCalibratedRed:...];
                break;
            case 4:
                aBackgroundColor = [NSColor colorWithCalibratedRed:...];    
                break;
            case 5:
                aBackgroundColor = [NSColor colorWithCalibratedRed:...];        
                break;
            case 6:
                aBackgroundColor = [NSColor colorWithCalibratedRed:...];            
                break;
            case 7:
                aBackgroundColor = [NSColor colorWithCalibratedRed:...];        
                break;
        }
        // Draw border first.
        ...
        // Draw label color.
        ...
    } 
    // Label value of '0' indicates that no label was assigned.
    if ([[self labelValue] intValue] == 0) {
        NSBezierPath *aPath = [NSBezierPath bezierPathWithRoundedRect: ...];
        [[NSColor clearColor] set];
        [aPath fill];
    }
}
4

1 に答える 1

0

通知を使用してすべてを再実装しました。バインディングを使用して動作させることができませんでした。これが私がしたことです:

(画面の左側)のコントローラーは、NSOutlineView次の方法を使用して要素のビューを配布します。

- (NSView *) outlineView: (NSOutlineView *) outlineView viewForTableColumn: (NSTableColumn *) tableColumn item: (id) anItem

ファイルに関連付けられたエンティティ(画像、PDFなど)がアウトラインビューに追加されると、その特定のアイテムのアイテムビュー(のカスタムサブクラス)は、エンティティのプロパティNSTableCellViewへの変更に対する関心を登録します。labelValue

[[NSNotificationCenter defaultCenter] addObserver: aView selector: @selector(labelValueChanged:) name: @"LabelValueChanged" object: nil];

labelValueプロパティの変更が発生すると(画面の右側にあるボタンの1つをクリックして)、そのコントローラーは通知を発行します。

[[NSNotificationCenter defaultCenter] postNotificationName:@"LabelValueChanged" object:[self selectedSource]];

通知システムを通じて、メソッドlabelValueChanged:は(内の)アイテムビューによって呼び出され、NSOutlineView実際にラベルを描画するカスタムビューコンポーネントの表示を無効にします。

- (void) labelValueChanged: (NSNotification*) aNotification {
    // A notification was received that the label was changed. Mark the label object of the receiver
    // if the object in the notification (anObject) matches the object of the receiver (objectValue).
    id anObject = [aNotification object];
    if (anObject == [self objectValue]) {
        [[self label] setNeedsDisplay:YES];
    }
}

@KenThomasesの提案に感謝します。

于 2012-05-20T16:40:20.567 に答える