如何刷新弹出窗口

问题描述

我正在学习Swift和SwiftUI,并可能会通过编写一些教程来编写StatusBar App,从而涉足更深的领域。

这是一些有用的简化版本。目的是要了解我目前仅显示的最前端的应用程序。

内容视图中的代码第一次实现了我想要的功能,但是从那以后,它不再运行。

我该怎么做才能刷新内容视图?

我正在使用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连接在一起。