【问题标题】:SwiftUI: Run code when window closed macOSSwiftUI:关闭窗口时运行代码 macOS
【发布时间】:2021-03-27 13:57:16
【问题描述】:

我以传统方式打开了我的窗口,但我想在通过单击关闭框(红色按钮)关闭窗口时运行一些代码。有什么好的方法吗?

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能做什么。

标签: macos swiftui window


【解决方案1】:

很好的问题.. 前段时间我也为这个问题苦苦挣扎过。

您可以使您的AppDelegate 或类符合NSWindowDelegate 协议。

然后将self作为窗口的委托传递

myWindow.delegate = self

并实现以下功能以通过关闭动作通知

func windowShouldClose(_ sender: NSWindow) -> Bool
{}

编辑:

在使用 SwiftUI 生命周期时,可以添加AppDelegate。你也可以实现你自己的WindowManager 类。这是一个例子:

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 中创建并保存该类,然后通过此管理器打开 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
                }
        }
    }
}

【讨论】:

  • 你会如何在 SwiftUI 中做到这一点?
  • 在我的 SwiftUI 中,我有 AppDelegate。您使用哪个生命周期?
  • 我正在使用 SwiftUI 应用协议。
  • 感谢您制作精美的文档和示例代码。真的很感激。
【解决方案2】:

如果您要运行的代码独立于上下文,那么最简单的解决方案是替换窗口的关闭操作并在那里运行您的代码,例如

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 
    }
}

如果你想用捕获的变量执行一些闭包,那么方法是相同的,但使用自定义处理程序类,它将持有窗口和闭包来执行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-24
    • 1970-01-01
    • 2021-04-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多