いくつかの追加のWeb検索と実験を通して、私は自分の質問のほとんどに答えることができます。
NSOUTLINEVIEWの最初の列のみを強調表示する
NSOutlineViewをサブクラス化して実装することにより、最初の列の選択された行にのみ選択のハイライトを表示させることができました。
- (void)highlightSelectionInClipRect:(NSRect)clipRect
{
NSRange visibleRowIndexes = [self rowsInRect:clipRect];
NSIndexSet *selectedRowIndexes = [self selectedRowIndexes];
NSInteger currentRow = visibleRowIndexes.location;
NSInteger lastRow = currentRow + visibleRowIndexes.length;
NSColor *highlightColor;
//Determine color of selection bar based on key/main/first responder status.
if (self == [[self window] firstResponder] && [[self window] isMainWindow] && [[self window] isKeyWindow]) {
highlightColor = [NSColor colorWithDeviceRed:0.0 green:0.0 blue:0.3 alpha:1.0];
} else
highlightColor = [NSColor lightGrayColor];
}
[highlightColor setFill];
//Get the Rect of only the name column. This is the only column that will be highlighted.
//We'll intersect this rect with the row rect for the area to fill in.
NSInteger nameColumn = [self columnWithIdentifier:@"name"];
NSRect nameColumnRect = [self rectOfColumn:nameColumn];
while (currentRow < lastRow) {
if ([selectedRowIndexes containsIndex:currentRow]) {
NSRect drawRect = NSIntersectionRect([self rectOfRow:currentRow], nameColumnRect);
NSRectFill(drawRect);
}
currentRow++;
}
}
次のように、カスタムNSCellサブクラスのdrawInteriorWithFrame:inView:メソッドをオーバーライドして、標準のハイライトが描画されないようにする必要があることに注意してください。
-(void) drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
//do drawing here...don't call super.
}
したがって、質問の一部に対する解決策があります。これが「正しい」方法でない場合は、私に知らせてください:)。
VIS / LOCK列のクリック/ドラッグは、選択を変更
しないでください。
-(NSIndexSet *) outlineView:(NSOutlineView *)outlineView selectionIndexesForProposedSelection:(NSIndexSet *)proposedSelectionIndexes
方法。可視性またはロック列で発生したドラッグの途中にいる場合は、現在のselectedRowsを返すだけで、選択を同じに保つことができます。私はまだこれを実装していませんが、最終的な問題が解決されれば簡単になるはずです(以下を参照)。
状態を変更するために可視性/ロックされた列を上下にドラッグする
私はこれに本当に近づいています。カスタムNSCellでは、次の3つのメソッドをオーバーライドしました。
-(BOOL) startTrackingAt:(NSPoint)startPoint inView:(NSView *)controlView
-(BOOL) continueTracking:(NSPoint)lastPoint at:(NSPoint)currentPoint inView:(NSView *)controlView
-(void) stopTracking:(NSPoint) lastPoint at:(NSPoint)stopPoint inView:(NSView *)controlView mouseIsUp:(BOOL)flag
私は私の最後の問題に取り掛かっています、そしてここにそれがあります:私はいつドラッグ操作の中にいるのか、そしていつドラッグ操作が終了するのかを知る必要があります。これを行うには2つの方法があります。
オーバーライドしない場合
+(BOOL) prefersTrackingUntilMouseUp
NSCellサブクラスで(デフォルトのNO値を返すため)、セルを離れてドラッグ操作中に次のセルに移動するたびに、stopTracking:at:inView:mouseIsUp:メッセージを受け取ります...つまり、そのメソッドを使用して、ドラッグ操作がいつ実行されるかを判別しないでください。
代わりに私がオーバーライドする場合
+(BOOL) prefersTrackingUntilMouseUp
YESを返すと、stopTrackingが表示されます:...マウスを上に向けた場合にのみ呼び出します。これはすばらしいことです...しかし、問題は、テーブルがmouseDownまたはドラッグ中にセルのUIを更新していないように見えることです。セル内。たとえば、startTracking:...メソッドで、セルのobjectValueをnilに設定すると(その画像が表示されなくなるように)、マウスボタンが上に戻るか、カーソルが細胞。(prefersTrackingUntilMouseUpがNOを返した場合、すぐに更新されます)。
したがって、セルのUIをすぐに(mouseDownで)更新できるだけでなく、ドラッグ操作がいつ完了したかを知る方法も必要です。これがパズルの最後のピースです。誰か助けてもらえますか?