1

我有一个基于视图NSOutlineView,它显示来自核心数据存储的条目(源实体)。大纲视图中的视图使用自定义控件,该控件被实现为NSView. 此控件根据数值 (0-7) 显示圆形彩色标记。此值存储为 Source 实体的属性,旨在作为一种实现类似 Finder 的标记方法的方法。

整个事情都是使用与 IB 的绑定来连接的。

我附上了一张截图,希望能让我的意图清楚。

这一切都很好,但对于一个非常烦人的细节。当数值改变时(从屏幕右侧),自定义控件仅在大纲视图中的选择改变时更新。显然,立即反映这种变化会更好,但到目前为止我失败了。我尝试了各种场景,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 属性发生更改时(通过单击屏幕右侧的按钮之一),该控制器会触发通知:

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

通过 Notification 系统,该方法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 回答