NSTableView:右键单击行时出现蓝色轮廓

6
我想知道如何在右键单击NSTableView / NSOutlineView中的行时摆脱Cocoa绘制的蓝色轮廓线。这似乎不是传统的“高亮”或“焦点环”,如果我没有弄错的话 - 那么它实际上是什么?
我目前正在完全自己绘制自定义NSCell,但我无法弄清楚如何:
* 也自己绘制此轮廓线,或者
* 摆脱它,或者
* 至少更改其颜色
任何提示都非常欢迎!谢谢!
3个回答

13

很遗憾,我不知道有任何文档记录的方法可以做到这一点,除非你编写自己的表格视图替换。

要重写的方法是:

- (void)drawContextMenuHighlightForRow:(NSInteger)row;
请向苹果提出改进请求,这样将来您就不必依赖未记录的方法来实现您想要的功能。看起来其他两个表视图高亮方法在10.6中可以进行自定义,但是这一个不能。我一直认为它看起来有点笨重,但是它必须指示菜单引用的行(不一定与高亮的行相同)。

谢谢,我有一段时间没有做64位的Cocoa了。 - Nicholas Riley
这是一个未经记录的API。请问它是否能通过Mac应用商店审核流程? - Aravindhan
不,通常这样做无法通过Mac App Store的审核。 (在Mac App Store出现之前,我发布了这个答案,所以那时候这不是一个问题!) - Nicholas Riley

2

我的NSTableView *mainTableView没有被子类化,所以我在上下文菜单打开之前将其删除:

- (void)menuWillOpen:(NSMenu *)menu{
     NSInteger rightClicked = [mainTableView clickedRow];
     [mainTableView selectRowIndexes:[NSIndexSet indexSetWithIndex:rightClicked] byExtendingSelection:NO];
     [mainTableView deselectRow: rightClicked];
     [mainTableView reloadData];
    {

reloadData是不必要的,但这是正确的做法。 - Zsolt Szatmari

0

这是我尝试重新绘制这些轮廓的结果:

import Cocoa

class TemplateOutlineView: NSOutlineView {
    
    private static let focusLineWidth: CGFloat = 2.0
    private static let focusLineColor = NSColor.controlAccentColor
    
    @objc
    func drawContextMenuHighlightForRow(_ row: Int) {
        guard !inLiveResize else { return }
        guard let ctx = NSGraphicsContext.current?.cgContext else { return }
        let rects = [CGRect](arrayLiteral: rect(ofRow: row))
        
        ctx.setLineWidth(TemplateOutlineView.focusLineWidth)
        ctx.setStrokeColor(TemplateOutlineView.focusLineColor.cgColor)
        
        let outerRect = bounds
            .insetBy(dx: 0.0, dy: 0.5)
            .offsetBy(dx: 0.0, dy: 0.5)
        for rect in rects.filter({ outerRect.intersects($0) }) {
            let innerRect = rect.intersection(outerRect)
            if innerRect.height > rect.height + 2.0 {
                ctx.addRect(innerRect
                                .insetBy(dx: TemplateOutlineView.focusLineWidth, dy: TemplateOutlineView.focusLineWidth + 0.5)
                                .offsetBy(dx: 0.0, dy: -0.5)
                )
            } else {
                ctx.addRect(rect
                                .insetBy(dx: TemplateOutlineView.focusLineWidth, dy: TemplateOutlineView.focusLineWidth + 0.5)
                                .offsetBy(dx: 0.0, dy: -0.5)
                )
            }
        }
        
        ctx.strokePath()
    }
    
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接