gpt4 book ai didi

objective-c - 在基于 View 的 NSTableView 上自定义右键单击突出显示

转载 作者:太空狗 更新时间:2023-10-30 03:36:44 25 4
gpt4 key购买 nike

我有一个基于 View 的 NSTableView,带有一个自定义 NSTableCellView 和一个自定义 NSTableRowView。我自定义了这两个类,因为我想更改每一行的外观。通过实现 [NSTableRowView draw...] 方法,我可以更改背景、选择、分隔符和拖动目标突出显示。

我的问题是:如何更改在右键单击该行并出现菜单时出现的突出显示?

例如,这是常态:

我想将方形高亮更改为圆形高亮,如下所示:

我想这会在 NSTableRowView 中通过调用 drawMenuHighlightInRect: 之类的方法来完成,但我找不到它。另外,如果我在我的子类中自定义了所有绘图方法,并且我不调用父类(super class),那么 NSTableRowView 类怎么能这样做呢?这是表格自己画的吗?

编辑:

经过更多的实验,我发现可以通过将 tableview 设置为源列表来实现圆形高亮。尽管如此,我还是想知道如何自定义它。

最佳答案

我知道我为 OP 提供任何帮助有点晚了,但希望这可以为其他人节省一点时间。我将 NSTableRowView 子类化以实现右键单击上下文菜单突出显示(为什么 Apple 没有公共(public)绘图方法来覆盖它超出了我的范围)。这是它的全部荣耀:

BSDSourceListRowView.h

#import <Cocoa/Cocoa.h>

@interface BSDSourceListRowView : NSTableRowView

// This needs to be set when a context menu is shown.
@property (nonatomic, assign, getter = isShowingMenu) BOOL showingMenu;

@end

BSDSourceListRowView.m

#import "BSDSourceListRowView.h"

@implementation BSDSourceListRowView

- (void)drawBackgroundInRect:(NSRect)dirtyRect
{
[super drawBackgroundInRect:dirtyRect];

// Context menu highlight:
if ( self.isShowingMenu ) {
[self drawContextMenuHighlight];
}
}

- (void)drawContextMenuHighlight
{
BOOL selected = self.isSelected;
CGFloat insetY = ( selected ) ? 2.f : 1.f;
NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:NSInsetRect(self.bounds, 2.f, insetY) xRadius:6.f yRadius:6.f];
NSColor *fillColor, *strokeColor;

if ( selected ) {
fillColor = [NSColor clearColor];
strokeColor = [NSColor whiteColor];
} else {
fillColor = [NSColor colorWithCalibratedRed:95.f/255.f green:159.f/255.f blue:1.f alpha:0.12f];
strokeColor = [NSColor alternateSelectedControlColor];
}

[fillColor setFill];
[strokeColor setStroke];

[path setLineWidth:2.f];
[path fill];
[path stroke];
}

- (void)drawSelectionInRect:(NSRect)dirtyRect
{
[super drawSelectionInRect:dirtyRect];
if ( self.isShowingMenu ) {
[self drawContextMenuHighlight];
}
}

- (void)setShowingMenu:(BOOL)showingMenu
{
if ( showingMenu == _showingMenu )
return;
_showingMenu = showingMenu;
[self setNeedsDisplay:YES];
}

@end

随意使用其中的任何一个,更改其中的任何一个,或者对其中的任何一个做任何你想做的事。玩得开心!


针对 Swift 3.x 更新:

SourceListRowView.swift

import Cocoa

open class SourceListRowView : NSTableRowView {

open var isShowingMenu: Bool = false {
didSet {
if isShowingMenu != oldValue {
needsDisplay = true
}
}
}

override open func drawBackground(in dirtyRect: NSRect) {
super.drawBackground(in: dirtyRect)
if isShowingMenu {
drawContextMenuHighlight()
}
}

override open func drawSelection(in dirtyRect: NSRect) {
super.drawSelection(in: dirtyRect)
if isShowingMenu {
drawContextMenuHighlight()
}
}

private func drawContextMenuHighlight() {

let insetY: CGFloat = isSelected ? 2 : 1
let path = NSBezierPath(roundedRect: bounds.insetBy(dx: 2, dy: insetY), xRadius: 6, yRadius: 6)
let fillColor, strokeColor: NSColor

if isSelected {
fillColor = .clear
strokeColor = .white
} else {
fillColor = NSColor(calibratedRed: 95/255, green: 159/255, blue: 1, alpha: 0.12)
strokeColor = .alternateSelectedControlColor
}

fillColor.setFill()
strokeColor.setStroke()

path.lineWidth = 2
path.fill()
path.stroke()
}

}

注意:我还没有真正运行过这个,但我很确定这应该可以在 Swift 中完成。

关于objective-c - 在基于 View 的 NSTableView 上自定义右键单击突出显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9619664/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com