通过一些额外的网络搜索和实验,我可以回答我自己的大部分问题:
仅突出显示 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 中,我重写了以下三种方法:
-(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
我要解决我的最后一个问题,这里是:我需要知道我何时在拖动操作中以及拖动操作何时完成。我有两种方法可以做到这一点:
如果我不覆盖
+(BOOL) prefersTrackingUntilMouseUp
在我的 NSCell 子类中(所以它返回默认的 NO 值),然后我每次离开一个单元格并在拖动操作期间转到下一个单元格时都会收到一个 stopTracking:at:inView:mouseIsUp: 消息......这意味着我可以'不要使用该方法来确定拖动操作何时完成。
相反,如果我确实覆盖
+(BOOL) prefersTrackingUntilMouseUp
并返回 YES,我得到一个 stopTracking:... 仅在鼠标启动时调用,这很好...但问题是表格似乎没有更新 mouseDown 上的单元格的 UI 或当我拖动时细胞内。例如,在 startTracking:... 方法中,如果我将单元格的 objectValue 设置为 nil(以便不再显示其图像),直到鼠标按钮返回或光标离开细胞。(当 prefersTrackingUntilMouseUp 返回 NO 时,它会立即更新)。
因此,我既需要能够立即(在 mouseDown 上)更新单元格的 UI,也需要有办法知道拖动操作何时完成。这是拼图的最后一块。任何人都可以帮忙吗?