Reputation: 1
I am working on a project for removing maximize, minimize and close buttons which we can see in every window in every App/projects build with Xcode for macOS in SwiftUI-life cycle. How could I do this?
PS: Please consider I am coding on SwiftUI-life cycle/macOS and if your code or way is not compatible with that then I could not make use of it. thanks for help and your time.
Update, date 05-March-2022: The question is still open and looks for a SwiftUI approach. You can answer this question with SwiftUI api.
Upvotes: 14
Views: 6397
Reputation: 11666
my two cents about using different approaches, integrating the previous nice solution from "shufflingb". Googling around and making some tests, I assemble another solution based on AppDelegate method. Hoping can help, I did prepare a project in gitHub with both approaches using a "const" (see below "let") to switch between approaches,
(https://github.com/ingconti/HideMacOsWindowButtons)
Here just some code for AppDelegate approach:
As a last side note, you cannot in any way to use it under Catalyst.
class MyAppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
// 1st method:
if USE_APP_DELEGATE{
customize(window: NSApplication.shared.windows.first)
}
}
}
@main
struct HideMacOsWindowButtonsApp: App {
@NSApplicationDelegateAdaptor private var appDelegate: MyAppDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
customise will do as per previous code:
//let USE_APP_DELEGATE = true
let USE_APP_DELEGATE = false
import AppKit
let ActiveNotif = NSApplication.didBecomeActiveNotification
typealias Window = NSWindow
fileprivate var count = 0
func customize(window: Window?) {
count+=1
print(USE_APP_DELEGATE ? "using App delegate" : "using notification", count)
guard let window = window else{
return
}
//window.titleVisibility = .hidden
//window.titlebarAppearsTransparent = true
window.isOpaque = false
window.backgroundColor = NSColor.green
window.standardWindowButton(.zoomButton)?.isHidden = true
window.standardWindowButton(.closeButton)?.isHidden = true
window.standardWindowButton(.miniaturizeButton)?.isHidden = true
}
I did add:
fileprivate var count = 0
just to verify no multiple calls (onlyy for debug).
Upvotes: 0
Reputation: 1947
Came across this question when looking to do similar myself so thought I'd add answer for posterity - or at least until Apple decides to make SwiftUI work nicely on macOS.
Anyway, the trick is to get hold of the window that holds the SwiftUI View and then tweak that. Easiest approach seems to be to listen for NSApplication
's didBecomeActiveNotification
and then grab a reference from NSApplication.shared
mainWindow
, keyWindow
(or possibly filter it out by title from windows
) as works best for the app in question.
Example of this using mainWindow
for a helloWorld program...
struct ContentView: View {
var body: some View {
Text("Hello, world!")
.padding()
.frame(minWidth: 200, minHeight: 200)
.navigationTitle("Undecorated")
.onReceive(NotificationCenter.default.publisher(for: NSApplication.didBecomeActiveNotification), perform: { _ in
NSApp.mainWindow?.standardWindowButton(.zoomButton)?.isHidden = true
NSApp.mainWindow?.standardWindowButton(.closeButton)?.isHidden = true
NSApp.mainWindow?.standardWindowButton(.miniaturizeButton)?.isHidden = true
})
}
}
Notes
Although the buttons are gone from the window it is important to note that the menu entries and hotkeys for maximising, hiding and killing the window are still fully operational. That functionallity has to be removed separately from customising the window appearance.
The alternative method I've seen to get hold of the window is to add an dummy "Find My Window" type View to the UI that uses AppKit to create it, and grabs a reference to the window when it does so. There is a nice exposition of this approach over on LostMoa's blog here.
Would be very interested if anyone has found anything better.
Upvotes: 11