How do I make a SwiftUI view fullscreen running Mac OS, Catalina or Big Sur?
SwiftUI Fullscreen Mac os
OK got it!
First start the Xcode project with LifeCycle -> AppKit App Delegate, not SwiftUI App.
In the AppDelegate.swift file add:
let mainScreen: NSScreen = NSScreen.screens[0]
window.contentView?.enterFullScreenMode(mainScreen)
at the end of func applicationDidFinishLaunching. Looks like this:
class AppDelegate: NSObject, NSApplicationDelegate
{
var window: NSWindow!
func applicationDidFinishLaunching(_ aNotification: Notification)
{
// Create the SwiftUI view that provides the window contents.
let contentView = ContentView()
// Create the window and set the content view.
window = NSWindow(
contentRect: NSRect(x: 0, y: 0, width: 480, height: 300),
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered, defer: false)
window.makeKeyAndOrderFront(self)
window.isReleasedWhenClosed = false
window.center()
window.setFrameAutosaveName("Main Window")
window.contentView = NSHostingView(rootView: contentView)
window.contentView?.enterFullScreenMode(mainScreen)
}
func applicationWillTerminate(_ aNotification: Notification)
{
// Insert code here to tear down your application
}
}
And finally set the background color of contentView to white, otherwise it will look dirty gray.
Would be nice to switch fullScreen on and off for different views, still digging.
First start the Xcode project with LifeCycle -> AppKit App Delegate, not SwiftUI App.
In the AppDelegate.swift file add:
let mainScreen: NSScreen = NSScreen.screens[0]
window.contentView?.enterFullScreenMode(mainScreen)
at the end of func applicationDidFinishLaunching. Looks like this:
class AppDelegate: NSObject, NSApplicationDelegate
{
var window: NSWindow!
func applicationDidFinishLaunching(_ aNotification: Notification)
{
// Create the SwiftUI view that provides the window contents.
let contentView = ContentView()
// Create the window and set the content view.
window = NSWindow(
contentRect: NSRect(x: 0, y: 0, width: 480, height: 300),
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered, defer: false)
window.makeKeyAndOrderFront(self)
window.isReleasedWhenClosed = false
window.center()
window.setFrameAutosaveName("Main Window")
window.contentView = NSHostingView(rootView: contentView)
Code Block // start App in fullScreen mode
let mainScreen: NSScreen = NSScreen.screens[0]window.contentView?.enterFullScreenMode(mainScreen)
}
func applicationWillTerminate(_ aNotification: Notification)
{
// Insert code here to tear down your application
}
}
And finally set the background color of contentView to white, otherwise it will look dirty gray.
Would be nice to switch fullScreen on and off for different views, still digging.
For a SwiftUI macOS App, I came up with this solution to enter full screen. In my use case I want the app to go full screen immediately on launch, but you can do this at any point.
import SwiftUI
@main
struct MacApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.onAppear {
DispatchQueue.main.asyncAfter(0.1) {
if let window = NSApplication.shared.windows.last {
window.toggleFullScreen(nil)
}
}
}
}
}
}
I get this error with the SwiftUI though No exact matches in call to instance method 'asyncAfter'
@conath reply works great only fix "deadline":
@main
struct ArabicForKidsMacApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now()) {
if let window = NSApplication.shared.windows.last {
window.toggleFullScreen(nil)
}
}
}
}
}
}
Swift concurrency can tighten up this code:
var body: some Scene
{
DocumentGroup(newDocument: { Document() }) { _ in
ContentView()
.onAppear {
Task { @MainActor in NSApplication.shared.windows.last?.toggleFullScreen(nil) }
}
}
}
I found a solution for macOS deployment 14.4:
let window = NSApp.windows.first { $0.isKeyWindow }
window?.toggleFullScreen(nil)