0

I'm currently developing a SwiftUI desktop application and I'm facing an issue with window customization. I want to entirely remove the title bar from my application's window - this includes the traffic lights (close, minimize, maximize buttons) and the title.

Here is a simplified version of my current SwiftUI application structure:

@main
struct MyApp: App {
    @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    var body: some Scene {
        WindowGroup {
            MainView()
        }.windowStyle(HiddenTitleBarWindowStyle())
        .commands {
            CommandGroup(replacing: .windowArrangement) { }
        }
    }
}

In MyApp, I'm using HiddenTitleBarWindowStyle(), but it's not giving me the expected result. The application's window still has the title bar with traffic lights and title visible.

I'm aware that customization of the NSWindow instance could allow me to control the window's appearance, but it's unclear to me how to do that in the context of a SwiftUI application that starts from the @main struct.

Can anyone guide me on how to completely remove the title bar in my SwiftUI desktop application?

Thanks in advance.

jnpdx
  • 45,847
  • 6
  • 64
  • 94

1 Answers1

1

here is a demo for hiding the buttons and title bar using swiftui on macos. note: NSWindow is still nil during .onAppear. as an alternative you can access it after the app launches by responding to user input (option 1), or during app launch via AppDelegate (option 2).

Option 1 -- responding to button press

struct ContentView: View {
    var body: some View {
        ZStack {
            Color.clear
            Button {
                chromeless()
            } label: {
                Text("go chromeless")
            }
        }
    }
}

func chromeless() {
    if let window = NSApp.windows.first {
        //hide buttons
        window.standardWindowButton(.closeButton)?.isHidden = true
        window.standardWindowButton(.miniaturizeButton)?.isHidden = true
        window.standardWindowButton(.zoomButton)?.isHidden = true
        
        //hide title and bar
        window.titleVisibility = .hidden
        window.titlebarAppearsTransparent = true
    }
}

Option 2 -- At app launch

Based on this answer you can also hide the window chrome at app launch.

final class AppDelegate: NSObject, NSApplicationDelegate {
    func applicationDidFinishLaunching(_ notification: Notification) {
        chromeless()
    }
}

@main
struct AlreadyMacOSApp: App {
    @NSApplicationDelegateAdaptor(AppDelegate.self) var delegate
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
Fault
  • 1,115
  • 1
  • 7
  • 11
  • I tried your solution in my SwiftUI app, but the title bar still appears. I implemented chromeless() in AppDelegate and called it in MainView().onAppear. Here's my code: `func chromeless() { DispatchQueue.main.async { if let window = NSApp.mainWindow { window.standardWindowButton(.closeButton)?.isHidden = true window.titleVisibility = .hidden window.titlebarAppearsTransparent = true } } }` Title bar remains. Any suggestions? Thanks! – Perch Hakobyan May 30 '23 at 19:41
  • i will update my answer to show how to hide the chrome at app launch. unfortunately NSApp.mainWindow is still nil during `.onAppear`. but there's an easy work around. – Fault May 31 '23 at 06:27
  • Hey, your solution didn't quite do the trick for me. I ended up using NSPanel and hiding the main window. Still, I'm gonna tick your answer as 'approved'. It might help someone else out, who knows! – Perch Hakobyan May 31 '23 at 20:33