如何刷新弹出窗口

How to refresh Popup

我正在学习 Swift 和 SwiftUI,并且可能会按照一些教程编写 StatusBar 应用程序以深入学习。

这里是一些有用的精简版本。目的是了解最前面的应用程序,我暂时只是简单地展示一下。

内容视图中的代码第一次执行了我想要的操作,但从那以后,它不再 运行。

我需要做什么才能刷新内容视图?

我在 XCode 11.7.

//  AppDelegate.swift
import SwiftUI

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
    var popover: NSPopover!
    var statusBarItem: NSStatusItem!

    func applicationDidFinishLaunching(_ aNotification: Notification) {
        let contentView = ContentView()
        self.popover = NSPopover()
        self.popover.contentViewController = NSHostingController(rootView: contentView)

        self.statusBarItem = NSStatusBar.system.statusItem(withLength: 18)
        if let statusBarButton = self.statusBarItem.button {
            statusBarButton.title = "☰"
            statusBarButton.action = #selector(togglePopover(_:))
        }
    }
    
    @objc func togglePopover(_ sender: AnyObject?) {
        let statusBarButton=self.statusBarItem.button!
        if self.popover.isShown {
            popover.performClose(sender)
        }
        else {
            self.popover.show(relativeTo: statusBarButton.bounds, of: statusBarButton, preferredEdge: NSRectEdge.maxY)
        }
    }

//  ContentView.swift

import SwiftUI
import AppKit

struct ContentView: View {
    var body: some View {
        let application=NSWorkspace.shared.frontmostApplication
        let name=application?.localizedName ?? "Dunno"
        print("Got \(name)")
        return Text("Application: \(name)")
    }
}


您的 ContentView 中的应用程序名称在您实例化后固定。所以它不会对动作做出反应。这是一个解决方案:

AppDelegate.swift

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    var window: NSWindow!

    var popover: NSPopover!
    var statusBarItem: NSStatusItem!
    var applicationInfo = ApplicationInfo()

    func applicationDidFinishLaunching(_ aNotification: Notification) {
        // Create the SwiftUI view that provides the window contents.
        let contentView = ContentView(application: applicationInfo)
        self.popover = NSPopover()
        self.popover.contentViewController = NSHostingController(rootView: contentView)

        self.statusBarItem = NSStatusBar.system.statusItem(withLength: 18)
        if let statusBarButton = self.statusBarItem.button {
            statusBarButton.title = "☰"
            statusBarButton.action = #selector(togglePopover(_:))
        }
    }
    
    @objc func togglePopover(_ sender: AnyObject?) {
        let statusBarButton=self.statusBarItem.button!
        if self.popover.isShown {
            popover.performClose(sender)
        } else {
            applicationInfo.name = NSWorkspace.shared.frontmostApplication?.localizedName ?? "Dunno"
            self.popover.show(relativeTo: statusBarButton.bounds, of: statusBarButton, preferredEdge: NSRectEdge.maxY)
        }
    }
}

ContentView.swift:

class ApplicationInfo: ObservableObject {
    @Published var name: String
    init() {
        name = "Dunno"
    }
}

struct ContentView: View {
    @ObservedObject var application: ApplicationInfo
    var body: some View {
        return Text("Application: \(application.name)")
    }
}

View 和动作由 ApplicationInfo 连接在一起。