macOS浮窗NSPanel
macOS浮窗NSPanel

macOS浮窗NSPanel

NSPanel 是 macOS 中 NSWindow 的子类,它专门用于显示工具面板、小浮窗、辅助窗口等,比普通窗口(NSWindow)行为更轻量、更灵活。

初始化方法

它继承自 NSWindow,所以和NSWindow的 API 几乎都相同。

NSPanel(
    contentRect: NSRect,
    styleMask: NSWindow.StyleMask,
    backing: NSWindow.BackingStoreType,
    defer: Bool
)

这个是 NSPanel的最常用构造方法,四个参数如下:

1、contentRect: NSRect

说明:窗口的初始尺寸和位置(相对于屏幕左下角)。

类型:NSRect,通常用 NSRect(x: y: width: height:) 创建。

注意:这是内容区域大小(不包括标题栏),窗口框架会根据 styleMask 自动扩展。

contentRect: NSRect(x: 100, y: 100, width: 600, height: 400)

2、styleMask: NSWindow.StyleMask

说明:指定窗口的样式,如是否可关闭、可调整大小、有标题栏等。

类型:NSWindow.StyleMask,可以组合多个值。

常用枚举值:

.titled:带标题栏。

.closable:可关闭。

.miniaturizable:可最小化。

.resizable:可调整大小。

.fullSizeContentView:内容扩展到整个窗口,包括标题栏区域。

.borderless:无边框窗口(用于自定义外观)。

可组合使用,例如:

styleMask: [.titled, .closable, .resizable]

3、backing: NSWindow.BackingStoreType

说明:决定窗口如何缓存绘图内容。现在基本固定为 .buffered。

类型:NSWindow.BackingStoreType

常用值:

.buffered(推荐,默认值):所有绘图操作在内存中完成,macOS 推荐的方式。

其他值(如 .retained)已废弃,不推荐使用。

backing: .buffered

4、defer: Bool

说明:是否推迟窗口的屏幕分配(窗口 frame 是否立即与屏幕绑定)。

类型:Bool

推荐值:

false:立即分配(大多数场景下使用)

true:延迟分配(如果之后会修改 frame)

defer: false

常用属性

1、styleMask:.titled, .closable, .utilityWindow 等。

2、isFloatingPanel:true 浮在其他窗口上面(默认)。

3、hidesOnDeactivate:true 切出 App 后隐藏;常用于调色板。

4、becomesKeyOnlyIfNeeded:true 避免打断主窗口焦点。

5、isReleasedWhenClosed:true 自动释放(仅限 Objective-C,Swift 中用 WindowController 管)。

搭配NSWindowController

在Swift项目中使用NSPanel时,推荐封装到NSWindowController中,便于管理和复用:

struct TestView: View {
    var body: some View {
        VStack {
            Text("测试视图")
        }
        .frame(width: 200,height: 140)
    }
}

class PanelController: NSWindowController {
    convenience init() {
        let panel = NSPanel(
            contentRect: NSRect(x: 300, y: 300, width: 300, height: 200),
            styleMask: [.titled, .closable, .utilityWindow],
            backing: .buffered,
            defer: false
        )
        panel.title = "浮动面板"
        panel.isFloatingPanel = true
        panel.hidesOnDeactivate = false
        // 嵌入 SwiftUI 视图
        let host = NSHostingView(rootView: TestView())
        panel.contentView = host
        panel.makeKeyAndOrderFront(nil)
        self.init(window: panel)
    }
}

在SwiftUI中使用:

struct ContentView: View {
    var body: some View {
        VStack {
            Button("打开浮窗") {
                let controller = PanelController()
                controller.showWindow(nil)
            }
        }
    }
}

使用场景

1、颜色/字体/图层控制面板。

2、辅助调试浮窗。

3、自定义属性控制器(图层、特效)。

4、插件设置界面(比如 Final Cut 插件)。

总结

NSPanel可以创建浮动工具窗口,继承NSWindow,所以可以使用NSWindow的大部分属性和方法。

NSColorPanel和NSFontPanel其实就是NSPanel子类。

NSColorPanel.shared  // -> NSColorPanel : NSPanel
NSFontPanel.shared   // -> NSFontPanel  : NSPanel

也可以子类化 NSPanel 做自己的组件。

相关文章

1、macOS窗口NSWindow:https://fangjunyu.com/2025/07/01/macos%e7%aa%97%e5%8f%a3nswindow/

2、macOS管理窗口的控制器类NSWindowController:https://fangjunyu.com/2025/06/30/macos%e7%ae%a1%e7%90%86%e7%aa%97%e5%8f%a3%e7%9a%84%e6%8e%a7%e5%88%b6%e5%99%a8%e7%b1%bbnswindowcontroller/

   

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开发者。

欢迎加入我们的 微信交流群QQ交流群,交流更多精彩内容!
微信交流群二维码 QQ交流群二维码

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注