如何在保留默认窗口样式的同时完全移除NSPanel的标题栏?
解决NSPanel保留阴影圆角同时隐藏标题栏的SwiftUI方案
你当前的代码已经启用了.titled样式来获得阴影和圆角,但标题栏的布局占位仍会导致内容视图顶部偏移。以下是可以彻底解决问题的修正方案:
修正后的完整代码
import AppKit import SwiftUI class PopupWindow: NSPanel { init() { super.init( contentRect: NSRect(origin: CGPoint(), size: CGSize(width: 500, height: 90)), styleMask: [.nonactivatingPanel, .titled, .fullSizeContentView], backing: .buffered, defer: true ) setupWindow() setupContentView() } private func setupWindow() { level = .floating isFloatingPanel = true titlebarAppearsTransparent = true titleVisibility = .hidden titlebarSeparatorStyle = .none // 移除标题栏底部分隔线 // 隐藏所有标题栏按钮 standardWindowButton(.closeButton)?.isHidden = true standardWindowButton(.miniaturizeButton)?.isHidden = true standardWindowButton(.zoomButton)?.isHidden = true // 让内容视图向上偏移,覆盖原标题栏区域 contentInsets = NSEdgeInsets(top: -self.titlebarHeight, left: 0, bottom: 0, right: 0) } private func setupContentView() { let hostingView = NSHostingView(rootView: PopupView()) hostingView.autoresizingMask = [.width, .height] contentView = hostingView } override var canBecomeKey: Bool { true } override var canBecomeMain: Bool { true } } struct PopupView: View { @State private var text = "" var body: some View { VStack { TextEditor(text: $text) .frame(minHeight: 16, maxHeight: 160) .fixedSize(horizontal: false, vertical: true) .border(.black, width: 1) } .frame(minWidth: 500, minHeight: 90) .fixedSize() .border(.red) .ignoresSafeArea(.container, edges: .top) // 忽略顶部安全区域,消除标题栏占位空白 } }
关键修改说明
- 清除标题栏视觉残留:
- 移除标题栏底部的分隔线,隐藏所有标题栏按钮,彻底消除标题栏的可见元素。
- 调整窗口布局偏移:
- 通过
contentInsets让内容视图向上偏移标题栏高度,完全覆盖原标题栏区域。
- 通过
- SwiftUI视图适配:
- 添加
.ignoresSafeArea(.container, edges: .top),忽略系统为标题栏预留的安全区域,确保内容紧贴窗口顶部边缘。
- 添加
- 内容视图自动适配:
- 给
NSHostingView设置autoresizingMask,确保内容视图随窗口尺寸变化自动调整大小。
- 给
这样修改后,既能保留.titled样式带来的原生阴影和圆角效果,又能完全隐藏标题栏,让内容视图填满整个窗口。
内容的提问来源于stack exchange,提问作者Edgar
相关产品推荐
相关产品推荐

