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

Cocoa 基于NSView的自定义控件图形更新延迟。为什么?,cocoa,custom-controls,nsoutlineview,Cocoa,Custom Controls,Nsoutlineview,我有一个基于视图的NSOutlineView,它显示来自核心数据存储的源实体条目。outline视图中的视图使用自定义控件,该控件作为NSView的子类实现。此控件基于数值0-7显示圆形彩色标记。该值存储为源实体的属性,并用作实现类似查找器的标记方法的方法 整个过程都是通过IB绑定实现的 我附上了一个截图,希望能让我的意图更清楚 这一切都很好,但有一个非常恼人的细节。当数值从屏幕右侧更改时,仅当大纲视图中的选择更改时,自定义控件才会更新。显然,立即反映这一变化会更好,但到目前为止我失败了。我已经

我有一个基于视图的NSOutlineView,它显示来自核心数据存储的源实体条目。outline视图中的视图使用自定义控件,该控件作为NSView的子类实现。此控件基于数值0-7显示圆形彩色标记。该值存储为源实体的属性,并用作实现类似查找器的标记方法的方法

整个过程都是通过IB绑定实现的

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

这一切都很好,但有一个非常恼人的细节。当数值从屏幕右侧更改时,仅当大纲视图中的选择更改时,自定义控件才会更新。显然,立即反映这一变化会更好,但到目前为止我失败了。我已经尝试了各种场景的设置需求显示:是的,基本上都被忽略了

有什么想法吗

编辑:我使用自定义控件实现了一个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];
    }
}

我使用通知重新实现了整个过程。我无法使用绑定使其工作。以下是我所做的:

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

- (NSView *) outlineView: (NSOutlineView *) outlineView viewForTableColumn: (NSTableColumn *) tableColumn item: (id) anItem
将与文件(图像、PDF等)关联的实体添加到大纲视图时,该特定项的NSTableCellView的item view自定义子类会对该实体的labelValue属性的更改感兴趣:

[[NSNotificationCenter defaultCenter] addObserver: aView selector: @selector(labelValueChanged:) name: @"LabelValueChanged" object: nil];
当通过单击屏幕右侧的一个按钮来更改labelValue属性时,该控制器将发出通知:

[[NSNotificationCenter defaultCenter] postNotificationName:@"LabelValueChanged" object:[self selectedSource]];
通过通知系统,NSOutlineView中的项视图调用labelValueChanged:方法,从而使实际绘制标签的自定义视图组件的显示无效:

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

感谢@Kenthomass的建议。

我在屏幕右侧没有看到任何东西?显示更改数值时使用的代码。如果您构建了自定义视图类以显示彩色标记,并且使用绑定连接了对象,是否实现了自定义绑定?怎样您是否遵循@KenThomases:I中描述的技术实现了自定义绑定。请参阅我的编辑,了解我的-显然-不起作用的方法。好的。您的-drawRect:正在查询labelValue属性,但只有在视图上显式设置它时才会更改。它没有咨询模型,您也没有提供任何理由相信用户在细节视图中使用小部件所做的更改是设置单元格视图的属性。我想这只是模型的一部分。您必须为自定义视图实现绑定,或者让控制器将更改后的值传递给单元视图。