This worked the best for me.
struct ContentView: View {
@State private var windowSize: CGSize = .zero // Holds the window size
@State private var isPresented: Bool = false // State for modal presentation
var body: some View {
ZStack {
Button("Present") {
isPresented.toggle()
}
}
.background(WindowSizeReader(size: $windowSize)) // Reads window size
.sheet(isPresented: $isPresented) {
ModalView()
}
.frame(width: windowSize.width, height: windowSize.height)
}
}
struct WindowSizeReader: NSViewRepresentable {
@Binding var size: CGSize
func makeNSView(context: Context) -> NSView {
let view = NSView()
DispatchQueue.main.async {
if let window = view.window {
self.size = window.frame.size // Get window size
NotificationCenter.default.addObserver(forName: NSWindow.didResizeNotification, object: window, queue: .main) { _ in
self.size = window.frame.size
}
}
}
return view
}
func updateNSView(_ nsView: NSView, context: Context) {}
}
Window Size Reader: WindowSizeReader is an NSViewRepresentable that captures the NSWindow hosting your SwiftUI view and observes its size using NSWindow.didResizeNotification.
Dynamic Size Binding: The @State property windowSize is updated dynamically based on the app window's dimensions.
Apply Window Dimensions: The windowSize.width and windowSize.height are used to set the frame size.