I have a SwiftUI app with a toolbar with multiple WindowGroups. I want all of my windows except the main one to have a toolbar with behaviour similar to the Preview app, hiding/collapsing the toolbar when it is fullscreen.
I have .presentedWindowToolbarStyle(.unified) attached to my views and .windowStyle(.titleBar) attached to my WindowGroups.
I have tried searching for methods, asked ChatGPT multiple times and I have tried to find open-source SwiftUI apps with a collapsing toolbar but they all did not work because they were either about iOS or about an AppKit app. In code, I have tried different settings of .windowStyle and .presentedWindowToolbarStyle as well as setting .windowToolbarStyle.
I managed to achieve this by doing the following:
willUseFullScreenPresentationOptions
For the first step, you can create a NSViewRepresentable
like so:
struct HostingWindowFinder: NSViewRepresentable {
var callback: (NSWindow?) -> ()
func makeNSView(context: Self.Context) -> NSView {
let view = NSView()
DispatchQueue.main.async { self.callback(view.window) }
return view
}
func updateNSView(_ nsView: NSView, context: Context) {
DispatchQueue.main.async { self.callback(nsView.window) }
}
}
Now create the custom delegate like this:
class CustomWindowDelegate: NSObject, NSWindowDelegate {
override init() {
super.init()
}
func window(_ window: NSWindow, willUseFullScreenPresentationOptions proposedOptions: NSApplication.PresentationOptions = []) -> NSApplication.PresentationOptions {
return [.autoHideToolbar, .autoHideMenuBar, .fullScreen]
}
}
Finally, in your view, do this to set the window delegate:
struct ContentView: View {
private var customWindowDelegate = CustomWindowDelegate()
var body: some View {
Text("Hello World")
.background {
HostingWindowFinder { window in
guard let window else { return }
window.delegate = self.customWindowDelegate
}
}
}
}
And now whenever your ContentView
goes fullscreen, it will auto hide the toolbar which can be revealed by moving your cursor to the top.