在新窗口中打开视图的按钮 SwiftUI 5.3 for Mac OS X

mou*_*bat 8 macos window button nswindow swiftui

我想要一个按钮来打开一个新窗口并在 SwiftUI for MacOS 中加载一个视图(用于应用程序的首选项),但我不确定正确的方法。

我尝试创建一个函数并从按钮操作调用它,但在关闭新窗口时应用程序崩溃:

线程 1:EXC_BAD_ACCESS(代码=1,地址=0x20)

这是我的功能:

func openPreferencesWindow() {
    var preferencesWindow: NSWindow!
    let preferencesView = PreferencesView()
    // Create the preferences window and set content
    preferencesWindow = NSWindow(
        contentRect: NSRect(x: 20, y: 20, width: 480, height: 300),
        styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
        backing: .buffered,
        defer: false)
    preferencesWindow.center()
    preferencesWindow.setFrameAutosaveName("Preferences")
    preferencesWindow.contentView = NSHostingView(rootView: preferencesView)
    preferencesWindow.makeKeyAndOrderFront(nil)
}
Run Code Online (Sandbox Code Playgroud)

这是我调用它的按钮:

Button(action: {
    openPreferencesWindow()
}) {
    Text("Preferences").font(.largeTitle).foregroundColor(.primary)
}
Run Code Online (Sandbox Code Playgroud)

我觉得应该在 AppDelegate 中构建窗口,但我不确定我会如何调用它。

Asp*_*eri 7

您需要参考创建的首选项窗口(如主窗口)。

这是可能的解决方案(使用 Xcode 11.4 / macOS 10.15.5 测试)

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {

    var window: NSWindow!
    var preferencesWindow: NSWindow!    // << here

    @objc func openPreferencesWindow() {
        if nil == preferencesWindow {      // create once !!
            let preferencesView = PreferencesView()
            // Create the preferences window and set content
            preferencesWindow = NSWindow(
                contentRect: NSRect(x: 20, y: 20, width: 480, height: 300),
                styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
                backing: .buffered,
                defer: false)
            preferencesWindow.center()
            preferencesWindow.setFrameAutosaveName("Preferences")
            preferencesWindow.isReleasedWhenClosed = false
            preferencesWindow.contentView = NSHostingView(rootView: preferencesView)
        }
        preferencesWindow.makeKeyAndOrderFront(nil)
    }

    // ... other code
Run Code Online (Sandbox Code Playgroud)

现在按钮看起来像

Button(action: {
    NSApp.sendAction(#selector(AppDelegate.openPreferencesWindow), to: nil, from:nil)
}) {
    Text("Preferences").font(.largeTitle).foregroundColor(.primary)
}
Run Code Online (Sandbox Code Playgroud)