カスタムNSCellサブクラスを使用してNSProgressIndicatorを描画するNSOutlineViewがあります。各NSCellには、次のようrefreshing
にNSOutlineViewデリゲートメソッドによって設定されるプロパティがあります。willDisplayCell:forItem:
- (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, 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];
}
}
drawInteriorWithFrame:inView:
NSProgressIndicatorインスタンスの項目は、次のように、NSCellのクラス内で停止および開始されます。
- (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がすべてのアイテムの更新を終了すると、reloadData:
呼び出しがトリガーされます。これは、問題のすべてのセルを確実に更新し、最終的にNSProgressIndicatorsを削除するように見える唯一のものです。
私はここで何が間違っているのですか?