基于NSView的自定义控件绘图更新被延迟。为什么?

时间:2012-05-19 15:17:01

标签: cocoa custom-controls nsoutlineview

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

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

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

这一切都很好,但对于一个非常讨厌的细节。当数值更改时(从屏幕右侧),仅在更改大纲视图中的选择时才更新自定义控件。显然,立即反映这一变化会更好,但到目前为止我已经失败了。我已尝试使用setNeedsDisplay: YES的各种方案,这些方案基本上都被忽略了。

有什么想法吗?

enter image description here

编辑:我使用自定义控件实现了一个setter:

- (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];
    }
}

1 个答案:

答案 0 :(得分:0)

我使用通知重新实现了整个事情。我无法使用绑定工作。这是我做的:

NSOutlineView的控制器(屏幕的左侧部分)使用以下方法为其元素分配视图:

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

当将与文件关联的实体(图像,PDF等)添加到大纲视图中时,该特定项目的项目视图(NSTableCellView的自定义子类)会注册对{{{ 1}}实体的属性:

labelValue

当labelValue属性发生更改时(通过单击屏幕右侧的其中一个按钮),该控制器将触发通知:

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

在Notification系统中,方法[[NSNotificationCenter defaultCenter] postNotificationName:@"LabelValueChanged" object:[self selectedSource]]; 被项目视图(在labelValueChanged:中)调用,这使实际绘制标签的自定义视图组件的显示无效:

NSOutlineView

感谢@KenThomases的建议。