swiftswiftuinswindow

How can I access the height of a Mac app's main window using SwiftUI?


I've been following a tutorial to learn SwiftUI and build an app for my Mac. The tutorial has been assuming that I'm writing for an iPhone, which hasn't been a problem until just now.

I need to access the height of the screen, or in my case the window. The tutorial is using UIScreen.main.bounds.height to do so, but since UIScreen isn't available for Mac apps, I'm trying to find the Mac equivalent. I'm pretty sure that the window that I'm trying to access is of type NSWindow, but I don't see any ways of accessing width and height of an NSWindow in the documentation. On top of that, I don't know how I could even go about accessing the NSWindow since there I don't see a variable or anything holding that information.

This is the tutorial I'm following, and the part where I need the height is at the end of line 36 of this gist where it says UIScreen.main.bounds.height.

Is there an easy way to do this in a Mac app? I appreciate any help that can be offered.


Solution

  • In SwiftUI, independently if you are targeting iOS or macOS, to get the size of the screen you have to wrap the main view with GeometryReader. This way, you can easily access its size.

    struct ContentView: View {
        var body: some View {
            GeometryReader { geo in
                NavigationStack {
                    HStack {
                        NavigationLink(destination: One(screenSize: geo.size)) {
                            Text("One")
                        }
    
                        NavigationLink(destination: Two(screenSize: geo.size)) {
                            Text("Two")
                        }
                    }
                }
                .frame(width: geo.size.width, height: geo.size.height)
            }
        }
    }
    
    struct One: View {
        let screenSize: CGSize
        
        var body: some View {
            Text("I'm view One")
                .frame(width: screenSize.width, height: screenSize.height)
                .background(Color.green)
        }
    }
    
    struct Two: View {
        let screenSize: CGSize
        
        var body: some View {
            Text("I'm view Two")
                .frame(width: screenSize.width / 2, height: screenSize.height / 2)
                .background(Color.red)
        }
    }
    

    enter image description here