如何解决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
的子视图(在最右边为进度指示器设置一列很方便)。当它变为假时,删除相应的进度指示器。您还需要确保在这些进度指示器上适当地设置自动调整大小标志,以使它们在调整大纲视图的大小时四处移动。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。