objective-c - 基于 View 的自定义选择样式 "Source List"NSOutlineView

标签 objective-c macos cocoa nsoutlineview appkit

我正在使用一个基于 NSOutlineView 的 View ,它的 selectionHighlightStyle 设置为 NSTableViewSelectionHighlightStyleSourceList

我想覆盖某些行的选择样式(背景)并绘制不同的颜色/渐变。

到目前为止我尝试的是创建自定义 NSTableRowView 并通过 outlineView:rowViewForItem: 返回它。 我验证了我的自定义行 View 是由大纲 View 委托(delegate)创建和返回的。 但是,我在自定义行 View 中覆盖的所有方法都没有被调用。

我试图覆盖 drawBackgroundInRect:drawSelectionInRect:drawSeparatorInRect: 甚至 drawRect:。这些都不会被调用。

我怀疑大纲 View 在设置为源列表样式时会执行一些自定义“魔法”,但我在文档中没有发现任何表明自定义 NSTableRowView在这种情况下根本不会受到尊重。

最佳答案

当使用 NSTableViewSelectionHighlightStyleSourceList 时,AppKit 将带有自定义 Material 的单独 NSVisualEffectView 添加到行 View 以绘制背景。我提出了以下使用零私有(private) API 的解决方法,但如果 Apple 实现了其他一些突出显示行的方法,稍后可能会中断。

@class CustomHighlightRowSelectionView;
@interface CustomHighlightRowView : NSTableRowView

@property (nonatomic, strong) CustomHighlightRowSelectionView *selectionView;

@end

@interface CustomHighlightRowSelectionView : NSView

@property (nonatomic, getter=isEmphasized) BOOL emphasized;
@property (nonatomic, getter=isSelected) BOOL selected;

@end


@implementation CustomHighlightRowView

- (CustomHighlightRowSelectionView *)selectionView
{
    if (!_selectionView)
    {
        _selectionView = [[CustomHighlightRowSelectionView alloc] initWithFrame:NSZeroRect];
    }

    return _selectionView;
}

- (void)setEmphasized:(BOOL)emphasized
{
    [super setEmphasized:emphasized];
    self.selectionView.emphasized = emphasized;
}

- (void)setSelected:(BOOL)selected
{
    [super setSelected:selected];
    self.selectionView.selected = selected;
}

- (void)addSubview:(NSView *)aView positioned:(NSWindowOrderingMode)place relativeTo:(NSView *)otherView
{
    if (![aView isKindOfClass:[NSVisualEffectView class]])
    {
        [super addSubview:aView positioned:place relativeTo:otherView];
    }
    else
    {
        if (!self.selectionView.superview)
        {
            [super addSubview:self.selectionView positioned:place relativeTo:otherView];
            self.selectionView.frame = self.bounds;
        }
    }
}

- (void)setFrame:(NSRect)frame
{
    [super setFrame:frame];

    self.selectionView.frame = self.bounds;
}

- (void)setBounds:(NSRect)bounds
{
    [super setBounds:bounds];

    self.selectionView.frame = self.bounds;
}

@end

@implementation CustomHighlightRowSelectionView

- (void)setEmphasized:(BOOL)emphasized
{
    _emphasized = emphasized;
    [self setNeedsDisplay:YES];
}

- (void)setSelected:(BOOL)selected
{
    _selected = selected;
    [self setNeedsDisplay:YES];
}

- (void)drawRect:(NSRect)dirtyRect
{
    if (!self.selected)
    {
        return;
    }

    NSColor *fillColor = self.emphasized ? [NSColor alternateSelectedControlColor] : [NSColor secondarySelectedControlColor];
    [fillColor setFill];
    NSRectFill(dirtyRect);
}

@end

关于objective-c - 基于 View 的自定义选择样式 "Source List"NSOutlineView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26884021/

相关文章:

ios - 在 UITableViewCell 中重复一个标签

ios - 这段 Swift 代码在做什么? func somefunc(其中 : (_: NSLayoutConstraint) -> Bool)

swift - textDidChange 指向错误的 NSCollectionViewItem

cocoa - 将 CoreData 与对象一起使用?

objective-c - 使用 SearchBar 时出现 NSUnknownKeyException。此类不符合键名的键值编码

ios - 获取 iPad 中文件的物理位置

c - getenv - Mac OS X 和 Linux 上的环境变量

swift - sqlite3_open 在 swift Playground 而不是 swift 应用程序中工作

objective-c - Cocoa - 如何将特定窗口从 StatusMenu 置于前台

macos - Webview:区分 "Open in Popup"和 "Open in New tab"