SwiftUI:在 macOS 上关闭打开 window 会导致崩溃
SwiftUI: Closing opened window on macOS causes crash
我可以打开一个新的 window,但是如果我使用 window 的关闭按钮关闭它,我的应用程序就会崩溃。
import SwiftUI
struct ContentView: View
{
var body: some View
{
Button(action: {openMyWindow()},
label: {Image(systemName: "paperplane")})
.padding()
}
}
func openMyWindow()
{
var windowRef:NSWindow
windowRef = NSWindow(
contentRect: NSRect(x: 100, y: 100, width: 100, height: 600),
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered, defer: false)
windowRef.contentView = NSHostingView(rootView: WindowView())
windowRef.makeKeyAndOrderFront(nil)
}
struct WindowView: View
{
var body: some View
{
Text("Hello World")
.padding()
}
}
@main
struct Open_WindowApp: App
{
var body: some Scene
{
WindowGroup
{
ContentView()
}
}
}
我想我需要保持我的 windowRef 活跃,但我该怎么做?
我们需要参考 window,尝试以下方法
struct ContentView: View
{
@State private var windowRef: NSWindow?
var body: some View
{
Button(action: {openMyWindow()},
label: {Image(systemName: "paperplane")})
.padding()
}
func openMyWindow()
{
// handle previously opened window here somehow if needed
guard windowRef == nil else { return }
windowRef = NSWindow(
contentRect: NSRect(x: 100, y: 100, width: 100, height: 600),
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered, defer: false)
windowRef?.contentView = NSHostingView(rootView: WindowView())
windowRef?.makeKeyAndOrderFront(nil)
}
}
声明 windowRef 在 openMyWindow()
的范围之外
如果 window 已经存在,请放在前面,不要创建另一个。
防止 window 在关闭时被释放,
windowRef.isReleasedWhenClosed = false
(如下所示)(documentation),或
someGlobalWindowController = NSWindowController(window: w)
var windowRef: NSWindow?
func openMyWindow()
{
if let curWindow = windowRef {
curWindow.makeKeyAndOrderFront(nil)
return
}
let w = NSWindow(
contentRect: NSRect(x: 100, y: 100, width: 100, height: 600),
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered, defer: false)
w.contentView = NSHostingView(rootView: WindowView())
w.makeKeyAndOrderFront(nil)
w.isReleasedWhenClosed = false // <--- important
windowRef = w
}
我可以打开一个新的 window,但是如果我使用 window 的关闭按钮关闭它,我的应用程序就会崩溃。
import SwiftUI
struct ContentView: View
{
var body: some View
{
Button(action: {openMyWindow()},
label: {Image(systemName: "paperplane")})
.padding()
}
}
func openMyWindow()
{
var windowRef:NSWindow
windowRef = NSWindow(
contentRect: NSRect(x: 100, y: 100, width: 100, height: 600),
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered, defer: false)
windowRef.contentView = NSHostingView(rootView: WindowView())
windowRef.makeKeyAndOrderFront(nil)
}
struct WindowView: View
{
var body: some View
{
Text("Hello World")
.padding()
}
}
@main
struct Open_WindowApp: App
{
var body: some Scene
{
WindowGroup
{
ContentView()
}
}
}
我想我需要保持我的 windowRef 活跃,但我该怎么做?
我们需要参考 window,尝试以下方法
struct ContentView: View
{
@State private var windowRef: NSWindow?
var body: some View
{
Button(action: {openMyWindow()},
label: {Image(systemName: "paperplane")})
.padding()
}
func openMyWindow()
{
// handle previously opened window here somehow if needed
guard windowRef == nil else { return }
windowRef = NSWindow(
contentRect: NSRect(x: 100, y: 100, width: 100, height: 600),
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered, defer: false)
windowRef?.contentView = NSHostingView(rootView: WindowView())
windowRef?.makeKeyAndOrderFront(nil)
}
}
声明 windowRef 在
的范围之外openMyWindow()
如果 window 已经存在,请放在前面,不要创建另一个。
防止 window 在关闭时被释放,
windowRef.isReleasedWhenClosed = false
(如下所示)(documentation),或someGlobalWindowController = NSWindowController(window: w)
var windowRef: NSWindow?
func openMyWindow()
{
if let curWindow = windowRef {
curWindow.makeKeyAndOrderFront(nil)
return
}
let w = NSWindow(
contentRect: NSRect(x: 100, y: 100, width: 100, height: 600),
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered, defer: false)
w.contentView = NSHostingView(rootView: WindowView())
w.makeKeyAndOrderFront(nil)
w.isReleasedWhenClosed = false // <--- important
windowRef = w
}