NSOutlineView setNeedsDisplayInRect调用失败

问题描述

| 我有一个NSOutlineView,它使用自定义NSCell子类绘制nsprogressIndicator。每个NSCell都有一个NSOutlineView委托
willdisplayCell:forItem:
方法设置的
refreshing
属性,如下所示:
- (void)outlineView:(NSOutlineView *)outlineView willdisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
{
    cell.refreshing = item.refreshing;
}
每个项目实例都包含一个nsprogressIndicator,该启动和停止取决于该特定项目是否正在刷新。
- (nsprogressIndicator *)startProgressIndicator
{
    if(!self.progressIndicator)
    {
        self.progressIndicator = [[[nsprogressIndicator alloc] initWithFrame:NSMakeRect(0,16.0f,16.0f)] autorelease];
        [self.progressIndicator setControlSize:NSSmallControlSize];
        [self.progressIndicator setStyle:nsprogressIndicatorSpinningStyle];
        [self.progressIndicator setdisplayedWhenStopped:YES];
        [self.progressIndicator setUsesThreadedAnimation:YES];
        [self.progressIndicator startAnimation:self];
    }

    return self.progressIndicator;
}
- (void)stopProgressIndicator
{
    if(self.progressIndicator != nil)
    {
        NSInteger row = [sourceList rowForItem:self];

        [self.progressIndicator setdisplayedWhenStopped:NO];
        [self.progressIndicator stopAnimation:self];
        [[self.progressIndicator superview] setNeedsdisplayInRect:[sourceList rectOfRow:row]];
        [self.progressIndicator removeFromSuperviewWithoutNeedingdisplay];

        self.progressIndicator = nil;
    }

    for(ProjectListItem *node in self.children)
    {
        [node stopProgressIndicator];
    }
}   
nsprogressIndicator实例项在我的NSCell的
drawInteriorWithFrame:inView:
类中停止和启动,如下所示:
- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
    if(self.refreshing)
    {
        nsprogressIndicator *progressIndicator = [item progressIndicator];
        if (!progressIndicator)
        {
            progressIndicator = [item startProgressIndicator];
        }

        // Set the progress indicators frame here ...

        if ([progressIndicator superview] != controlView)
            [controlView addSubview:progressIndicator];

        if (!NSEqualRects([progressIndicator frame],progressIndicatorFrame)) {
            [progressIndicator setFrame:progressIndicatorFrame];
        }
    }
    else
    {
        [item stopProgressIndicator];
    }

    [super drawInteriorWithFrame:cellFrame inView:controlView];
}
我遇到的问题是,尽管正确地告知nsprogressIndicators停止,但是对stopProgressIndicator的调用却没有效果。这是未能触发刷新NSOutlineView行的代码。我已经手动检查了我对rectOfRow的调用返回的NSRect,并可以确认该值正确。
[self.progressIndicator setdisplayedWhenStopped:NO];
[self.progressIndicator stopAnimation:self];
[[self.progressIndicator superview] setNeedsdisplayInRect:[sourceList rectOfRow:row]];
[self.progressIndicator removeFromSuperviewWithoutNeedingdisplay];

self.progressIndicator = nil;
当NSOutlineView完成刷新其所有项目时,将触发“ 7”调用。这似乎是唯一可以可靠地更新所有相关单元格并最终删除nsprogressIndicators的事情。 我在这里做错了什么?     

解决方法

        在绘制事物时弄乱视图层次结构是不明智的做法。最好的办法是使用
NSProgressIndicator
NSCell
版本,但是
AppKit
则没有。 Daniel Jalkut对类似问题的回答中描述的解决方案可能是达到所需目标的最快途径。这是基本概念: 观察项目的“ 0”状态,而不是在绘制过程中使用“ 0”变量切换路径。变为true时,在given15ѭ项的位置添加
NSProgressIndicator
作为
NSOutlineView
的子视图(在最右边为进度指示器设置一列很方便)。当它变为假时,删除相应的进度指示器。您还需要确保在这些进度指示器上适当地设置自动调整大小标志,以使它们在调整大纲视图的大小时四处移动。     

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...