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/