如何防止 macOS 自动将 NSVisualEffectView 插入 NSScrollView

Fra*_* R. 5 macos cocoa appkit nsscrollview nsvisualeffectview

我通过将 a放入 aNSView以编程方式构建层次结构。我之前已经这样做过并且我的代码是正确的。NSStackViewNSScroller

视图层次结构是我所期望的,直到第一次通过运行循环(或显示)时,macOS Catalina(我认为是 Mojave)会自动将 a 插入NSVisualEffectView到视图层次结构中。这把我的自定义绘图弄乱了。

我创建的层次结构是

NSScrollView -> NSStackView -> stack subviews
Run Code Online (Sandbox Code Playgroud)

在第一个显示循环之前,滚动视图“丰富”了这一点:

NSScrollView -> NSClipView -> NSStackView -> stack subviews
Run Code Online (Sandbox Code Playgroud)

第一次显示后,NSVisualEffects View 被添加到与 NSClipView 相同的级别:

NSScrollView -> NSClipView          -> NSStackView -> stack subviews
             -> NSVisualEffectsView
Run Code Online (Sandbox Code Playgroud)

有没有办法告诉滚动视图我不想要视觉效果视图?

任何帮助,将不胜感激!

ix4*_*n33 3

当我尝试重新创建聚光灯窗口时,我遇到了同样的问题。下面的屏幕截图显示了视觉效果视图中的表格视图(包含在滚动视图中):

在此输入图像描述

在旧版本的 macOS 中,这里的不透明背景是在滚动视图(或剪辑视图)上绘制的背景,我们可以通过设置清晰的背景颜色或按照 Lucas 建议的设置来简单地删除drawBackgroundfalse

但是,由于在较新版本的 macOS(也许是 Catalina?)中插入了此视觉效果视图,因此这不起作用:

在此输入图像描述

它有一个不透明的内容背景材料,我没有找到任何与此行为相关的 API 或文档。


解决方法

对我有用的是在我的子类中隐藏插入的视觉效果视图NSScrollView

class ScrollView: NSScrollView {
    override func didAddSubview(_ subview: NSView) {
        super.didAddSubview(subview)

        if subview is NSVisualEffectView {
            subview.isHidden = true
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


更新

如果您使用的是NSTableView,而不是上面的“hack”,最好将表视图的样式设置为源列表:

// for macOS 11 Big Sur
tableView.style = .sourceList

// for macOS 10.15 Catalina and older
tableView.selectionHighlightStyle = .sourceList
Run Code Online (Sandbox Code Playgroud)

执行此操作时,系统会自动配置源列表外观(或侧边栏)的滚动视图和表格视图。更具体地说,滚动视图不插入视觉效果视图,而表视图的行视图是半透明的。