如何刷新 Swift 应用程序中的菜单项?

How do I refresh menu items in a Swift app?

我有一个菜单栏应用,需要在用户打开菜单时刷新其中一个菜单项。

我有一个函数可以提取机器当前使用的 IP 并将它们存储在一个变量中:addresses。通过 override func awakeFromNib() 调用菜单。我们有一个计时器功能,我曾尝试使用它来更新 addresses 变量,但无法弄清楚如何让菜单本身使用变量中的新数据进行更新。

我试过在 addresses 上使用 didSet 来更新变量,并且我已经将更新 addresses 的函数添加到 Timer 函数中,但这不会更新菜单,只会更新变量。

这是加载菜单的代码:

override func awakeFromNib() {
    Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateProcessTimer), userInfo: nil, repeats: true)

    statusItem.menu = statusMenu
    statusItem.image = icon

    // get computer information
    let compInfo = ComputerInfo()        
    let addresses = compInfo.getIPAddresses()
    let compName = compInfo.getComputerName()


    // present the computer info
    if let computerNameMenuItem = self.statusMenu.item(withTitle: "computerName") {
        computerNameMenuItem.title = compName ?? "unknown"
    }
    if let computerIPMenuItem = self.statusMenu.item(withTitle: "ipAddress") {
        computerIPMenuItem.title = addresses
    }   
}

就目前而言,它会在应用加载时设置菜单项,仅此而已。我想找到一种方法来在每次用户单击菜单时更新 computerIPMenuItem.title

--附加信息--

菜单 class 是一个调用 nib 文件的 NSObject, NSApplicationDelegate。在 nib 中,我们有一个带有 NSMenuItem place-holders 的菜单栏,上面引用的标题为 computerNameipAddress。不确定这是否有助于阐明为什么某些传统的 override func 调用不起作用。

另一个选项是:

override func layoutSubviews() {
    super.layoutSubviews()

    updateWhatYouNeed()
}

您需要将 statusMenu 委托设置为自己:

statusMenu.delegate = self

然后您可以使用此处理程序在显示菜单之前更新菜单:

func menu(NSMenu, update: NSMenuItem, at: Int, shouldCancel: Bool) -> Bool {
    if(update.tag == 1) { //where '1' should be the tag of the menu item you want to update
        //update your menu item
        update.title = "New Title";
    }
}

你的代码中的主要问题是你是按标题获取项目的,而你应该按标签获取它们,这样即使标题更新了你也可以检索它们