SwiftUI:运行 window 关闭 macOS 时的代码
SwiftUI: Run code when window closed macOS
我已经以传统方式打开了 window,但我想在 window 通过单击关闭框(红色按钮)关闭时 运行 一些代码。有什么好的方法吗?
func openMyWindow()
{
myWindow = (NSWindow(
contentRect: NSRect(x: 100, y: 100, width: 100, height: 600),
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered, defer: false))
myWindow!.contentView = NSHostingView(rootView: MyWindowView())
myWindow!.makeKeyAndOrderFront(nil)
}
好问题..我之前也曾在这个问题上挣扎过。
您可以让您的 AppDelegate
或 class 符合 NSWindowDelegate
协议。
然后通过self
作为window
的代表
myWindow.delegate = self
并实现以下功能以通过关闭操作通知
func windowShouldClose(_ sender: NSWindow) -> Bool
{}
编辑:
当你使用SwiftUI生命周期时,你可以添加一个AppDelegate
。您也可以实现自己的 WindowManager
class。这是一个例子:
class WindowManager : NSObject, NSWindowDelegate {
var popUpWindow : NSWindow? = nil
override init() {}
func openMyWindow()
{
popUpWindow = (NSWindow(
contentRect: NSRect(x: 100, y: 100, width: 100, height: 600),
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered, defer: false))
popUpWindow!.contentView = NSHostingView(rootView: PopUpView())
popUpWindow!.makeKeyAndOrderFront(nil)
popUpWindow?.delegate = self
}
func windowShouldClose(_ sender: NSWindow) -> Bool
{
print("Window will close")
return true
}
}
struct PopUpView : View {
var body: some View {
Text("This is a new popup view")
}
}
在您的 struct _: App
中创建并保持 class 并通过此管理器打开 Windows。
@main
struct macSwiftUICycleApp: App {
let persistenceController = PersistenceController.shared
let windowManager : WindowManager = WindowManager() //<< Here keep the instance of your WindowManager
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.managedObjectContext, persistenceController.container.viewContext)
.onAppear {
windowManager.openMyWindow() //<< Just a test to open another window on startup
}
}
}
}
如果您想要 运行 的代码独立于上下文,那么最简单的解决方案是替换 window 和 运行 您的代码的关闭操作,例如
func openMyWindow()
{
// ... other your code
myWindow!.contentView = NSHostingView(rootView: MyWindowView())
let closeButton = myWindow!.standardWindowButton(.closeButton) // << !!
closeButton?.action = #selector(NSWindow.doMyClose(_:)) // << !!
myWindow!.makeKeyAndOrderFront(nil)
}
extension NSWindow {
@objc
func doMyClose(_ sender: Any?) {
// ... run your code here
self.close() // << make standard window close
// ... or here
}
}
如果你想用捕获的变量执行一些闭包,那么方法是相同的,但使用自定义处理程序 class 将保存 window 和闭包来执行。
我已经以传统方式打开了 window,但我想在 window 通过单击关闭框(红色按钮)关闭时 运行 一些代码。有什么好的方法吗?
func openMyWindow()
{
myWindow = (NSWindow(
contentRect: NSRect(x: 100, y: 100, width: 100, height: 600),
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered, defer: false))
myWindow!.contentView = NSHostingView(rootView: MyWindowView())
myWindow!.makeKeyAndOrderFront(nil)
}
好问题..我之前也曾在这个问题上挣扎过。
您可以让您的 AppDelegate
或 class 符合 NSWindowDelegate
协议。
然后通过self
作为window
myWindow.delegate = self
并实现以下功能以通过关闭操作通知
func windowShouldClose(_ sender: NSWindow) -> Bool
{}
编辑:
当你使用SwiftUI生命周期时,你可以添加一个AppDelegate
。您也可以实现自己的 WindowManager
class。这是一个例子:
class WindowManager : NSObject, NSWindowDelegate {
var popUpWindow : NSWindow? = nil
override init() {}
func openMyWindow()
{
popUpWindow = (NSWindow(
contentRect: NSRect(x: 100, y: 100, width: 100, height: 600),
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered, defer: false))
popUpWindow!.contentView = NSHostingView(rootView: PopUpView())
popUpWindow!.makeKeyAndOrderFront(nil)
popUpWindow?.delegate = self
}
func windowShouldClose(_ sender: NSWindow) -> Bool
{
print("Window will close")
return true
}
}
struct PopUpView : View {
var body: some View {
Text("This is a new popup view")
}
}
在您的 struct _: App
中创建并保持 class 并通过此管理器打开 Windows。
@main
struct macSwiftUICycleApp: App {
let persistenceController = PersistenceController.shared
let windowManager : WindowManager = WindowManager() //<< Here keep the instance of your WindowManager
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.managedObjectContext, persistenceController.container.viewContext)
.onAppear {
windowManager.openMyWindow() //<< Just a test to open another window on startup
}
}
}
}
如果您想要 运行 的代码独立于上下文,那么最简单的解决方案是替换 window 和 运行 您的代码的关闭操作,例如
func openMyWindow()
{
// ... other your code
myWindow!.contentView = NSHostingView(rootView: MyWindowView())
let closeButton = myWindow!.standardWindowButton(.closeButton) // << !!
closeButton?.action = #selector(NSWindow.doMyClose(_:)) // << !!
myWindow!.makeKeyAndOrderFront(nil)
}
extension NSWindow {
@objc
func doMyClose(_ sender: Any?) {
// ... run your code here
self.close() // << make standard window close
// ... or here
}
}
如果你想用捕获的变量执行一些闭包,那么方法是相同的,但使用自定义处理程序 class 将保存 window 和闭包来执行。