在 window SwiftUI 5.3 for Mac OS X 中打开视图的按钮
Button to open view in new window SwiftUI 5.3 for Mac OS X
我想要一个按钮来打开一个新的 window 并在适用于 MacOS 的 SwiftUI 中加载一个视图(用于应用程序的首选项),但不确定正确的方法。
我尝试创建一个函数并从有效的按钮操作中调用它,但在关闭新的 window 时应用程序崩溃:
Thread 1: EXC_BAD_ACCESS (code=1, address=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)
}
这是我调用它的按钮:
Button(action: {
openPreferencesWindow()
}) {
Text("Preferences").font(.largeTitle).foregroundColor(.primary)
}
我觉得 window 应该在 AppDelegate 中构建,但我不确定我将如何调用它。
您需要参考已创建的首选项 window(如参考主要 window)。
这是可能的解决方案(使用 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
现在按钮看起来像
Button(action: {
NSApp.sendAction(#selector(AppDelegate.openPreferencesWindow), to: nil, from:nil)
}) {
Text("Preferences").font(.largeTitle).foregroundColor(.primary)
}
我想要一个按钮来打开一个新的 window 并在适用于 MacOS 的 SwiftUI 中加载一个视图(用于应用程序的首选项),但不确定正确的方法。
我尝试创建一个函数并从有效的按钮操作中调用它,但在关闭新的 window 时应用程序崩溃:
Thread 1: EXC_BAD_ACCESS (code=1, address=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)
}
这是我调用它的按钮:
Button(action: {
openPreferencesWindow()
}) {
Text("Preferences").font(.largeTitle).foregroundColor(.primary)
}
我觉得 window 应该在 AppDelegate 中构建,但我不确定我将如何调用它。
您需要参考已创建的首选项 window(如参考主要 window)。
这是可能的解决方案(使用 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
现在按钮看起来像
Button(action: {
NSApp.sendAction(#selector(AppDelegate.openPreferencesWindow), to: nil, from:nil)
}) {
Text("Preferences").font(.largeTitle).foregroundColor(.primary)
}