SwiftUI 更新主菜单 [已解决] kludgey

2024-05-14

真正的问题

你如何更新mainMenu在 SwiftUI 中,它真的可以工作吗?

我在 SwiftUI 中构建了一个基于 MacOS 文档的应用程序,其中包括所有内置的文件菜单命令(即关闭、保存、复制、重命名...等)

在保存文档之前,我会验证结构,并希望在存在任何验证错误时向用户显示模式对话框。

模式对话框只是一个简单的“确定/取消”对话框 - “确定”意味着用户很乐意保存带有验证错误的文件,“取消”则需要停止保存操作。

所以问题是:“如何拦截内置的‘保存’菜单命令来显示此对话框?

我试图覆盖.saveItemCommandGroup - 但这取代了all菜单项,我只想覆盖几个命令(“保存”和“另存为”),并且不想重新实现所有命令(而且我不确定我是否有能力这样做)

        .commands {
            CommandGroup(replacing: .saveItem) {
                // code goes here - but removes all of the in-built menus
            }
        }

我已经尝试过这个解决方案(在 SwiftUI 文档应用程序中,如何从函数内保存文档 https://stackoverflow.com/questions/68522523/in-a-swiftui-document-app-how-to-save-a-document-from-within-a-function)

并将其放入我的 AppDelegate 中

    public func applicationDidBecomeActive(_ notification: Notification) {
        let menu = NSApplication.shared.mainMenu!.items.first(where: { $0.title == "File" })!
        let submenu = menu.submenu!.items.first(where: { $0.title == "Save" })!
        submenu.action = #selector(showDialog)
    }

    @objc func showDialog() {
        var retVal: Int = 0

        let thisWindow: NSWindow? = NSApplication.shared.mainWindow

        let nsAlert: NSAlert = NSAlert()
        let cancelButton: NSButton = nsAlert.addButton(withTitle: "Cancel")
        cancelButton.tag = 1

        let okButton: NSButton = nsAlert.addButton(withTitle: "OK")
        okButton.tag = 0

        // The below code is replaced
        nsAlert.beginSheetModal(for: thisWindow!) { modalResponse in
            print(modalResponse)
            retVal = modalResponse.rawValue


            if retVal == 0 {
                print("save")
            } else {
                print("cancel")
            }
        }
    }

然而它实际上并没有调用showDialog功能。

编辑/更新

我在更新菜单时仍然遇到困难,但在上面的示例中调用beginModalSheet是不正确的,因为该进程将在后台运行。将调用更新为runModal()这将停止写入文件的任何后台进程。

    @objc func showDialog() {
        let nsAlert: NSAlert = NSAlert()
        let cancelButton: NSButton = nsAlert.addButton(withTitle: "Cancel")
        cancelButton.tag = 1

        let okButton: NSButton = nsAlert.addButton(withTitle: "OK")
        okButton.tag = 0

        let response: Int = nsAlert.runModal().rawValue
        if response == 0 {
            print("save")
            NSApp.sendAction(#selector(NSDocument.save(_:)), to: nil, from: nil)
        } else {
            print("cancel")
        }
    }

我在某处读到您需要在窗口出现之前设置菜单,并且我还读到您需要在设置 AppDelegate 之前设置菜单。

另一个编辑

看这个帖子隐藏 SwiftUI / MacOS 应用程序的编辑菜单 https://stackoverflow.com/questions/71309874/hiding-edit-menu-of-a-swiftui-macos-app

和这个评论

Thoughts:SwiftUI 要么有错误,要么他们真的不希望您删除 NSApp.mainMenu 中的顶级菜单。 SwiftUI 似乎重置了整个菜单,目前无法覆盖或自定义大多数细节(Xcode 13.4.1)。 CommandGroup(replacing: .textEditing) { } 式命令不允许您删除或清除整个菜单。当 SwiftUI 需要时,即使您没有指定任何命令,分配一个新的 NSApp.mainMenu 也会被破坏。


XCode 14.1 Swift 5

经过大量超级令人沮丧的搜索尝试和大量代码之后 - 我将问题简化为只是尝试更改名称save菜单项 - 如果我可以做到这一点 - 那么我也可以更改它的操作。

我是这样做的

我的 Tetsing 应用程序名为YikesRedux

Steps:

  1. 注册AppDelegate
  2. 覆盖applicationWillUpdate method
  3. 将菜单更新放在DispatchQueue.main.async closure
  4. 经过几天的搜索,你已经解决了这个问题,喜极而泣

YikesAppRedux.swift

import SwiftUI

@main
struct YikesReduxApp: App {
    @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate // <- Don't forget the AppDelegate

    var body: some Scene {
        DocumentGroup(newDocument: YikesReduxDocument()) { file in
            ContentView(document: file.$document)
        }
    }
}

AppDelegate.swift

import Foundation
import AppKit

public class AppDelegate: NSObject, NSApplicationDelegate {
    public func applicationWillUpdate(_ notification: Notification) {
        DispatchQueue.main.async {
            let currentMainMenu = NSApplication.shared.mainMenu

            let fileMenu: NSMenuItem? = currentMainMenu?.item(withTitle: "File")
            if nil != fileMenu {
                let saveMenu = fileMenu?.submenu!.item(withTitle: "Save")
                if nil != saveMenu {
                    print("updated menu")
                    saveMenu?.title = "Save Updated"
                }
            }
        }
    }
}

我认为这有点混乱 - 因为它在每次应用程序更新时运行(虽然不是很多,但当它确实发生时,您可以在控制台“更新菜单”中看到打印输出)

我确实尝试保留一个关于菜单是否更新的状态变量,以尝试不再这样做 - 但在多文档窗口环境中,您需要跟踪每个窗口......(而且 Swift 只会在需要的时候破坏菜单 - 所以它没有达到预期的效果。)

我几乎把菜单更新代码放在我能想到的所有地方

  • 每一个AppDelegate函数覆盖
  • 的初始化方法App, the ContentView
  • 关于文档读取功能/写入功能
  • 你能想到的 - 我把它放在那里(我什至有一个托管控制器,一个 NSViewRepresentable)

然后我将它们一一删除,直到找到解决方案。

如果有一种不那么笨拙的方法来做到这一点,我会很高兴。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SwiftUI 更新主菜单 [已解决] kludgey 的相关文章

  • 类型名称已知却未知?

    Xcode 突然显示了此错误 未知类型名称 我会解释一下 我的 StoriesViewController h import
  • App Store Connect 上传错误“您尚未获得云管理分发证书的访问权限”

    使用 Xcode 将 iOS 应用程序上传到 App Store Connect 自动管理签名 并收到此错误 查找和生成签名资产时发生以下错误 与苹果通讯失败 您尚未获得云管理分发证书的访问权限 请联系您团队的帐户持有人或管理员以授予您访问
  • git pull origin master 返回致命错误:无效的 refspec

    问题是这样的 每当我这样做时 git pull https github com username reponame github io git 接下来是网址 我没有遇到任何问题 但是当我这样做时 git pull origin maste
  • Xcode 6 beta 颜色选择器问题

    问题 颜色选择器没有拾取准确的颜色 这与此处列出的问题相同 Interface Builder 的颜色选择器中的颜色错误 https stackoverflow com questions 12686141 wrong color in i
  • “找不到开发者磁盘映像”

    最近我收到错误 找不到开发人员磁盘映像 我认为自从我将 iPhone 上的 iOS 更新到 9 1 后就会发生这种情况 如何解决该问题并使 Xcode 支持 iOS 9 1 设 备 Xcode 7 0 1 和 iOS 9 1 不兼容 您需要
  • 使用 Bash 按进程名称检查 Mac 进程是否正在运行

    如何使用 Bash 脚本中的进程名称检查 Mac OS X 上的进程是否正在运行 我正在尝试编写一个 Bash 脚本 如果进程已停止 它将重新启动进程 但如果进程仍在运行 则不执行任何操作 解析这个 ps aux grep v grep g
  • python 语言环境奇怪的错误。这究竟是怎么回事?

    所以今天我升级到了 bazaar 2 0 2 我开始收到这条消息 顺便说一句 我在雪豹上 bzr warning unknown locale UTF 8 Could not determine what text encoding to
  • Poppler 已安装:为什么在 python3 上使用 pdf2image 时出现错误?

    我正在使用Python3 7 4在 macOS 10 14 6 上 我正在尝试使用pdf2image将 pdf 文件转换为图像 所以我已经安装了poppler with Homebrew 当我尝试转换 PDF 时收到错误消息 Traceba
  • 当日期改变时 NSNotification?

    WebKit 的 WebHistory API 按日期分隔其项目 因此 当日期发生变化时 我需要重新分配任何 昨天 和 或 早些时候 今天 或 明天 标签 有 NSNotification 吗 或者我必须依赖 NSTimer 还是 perf
  • 不确定如何在使用故事板时正确子类化 UIApplication

    我想在 X 次用户不活动 没有触发触摸事件 后返回故事板的初始视图控制器 经过一些研究 我发现检测不活动的最常见方法是触发 NSTimer 并在事件触发时重置间隔 为了检测触发的事件 我们在 UIApplication 的子类中重写 UIA
  • SwiftUI 中的计算 (NSObject) 属性不会更新视图

    所以 我想要一个Text它根据我的 CoreData 模型的内容更改其内容 为此 我在 Xcode beta 4 中使用了计算属性 但它似乎不再起作用了 这是一个错误还是还有其他我没有看到的问题 我真正遇到的问题是我的视图 和计算的属性 似
  • SwiftUI NavigationView 从其内部开始

    因此 我在页面视图样式的 TabView 中嵌入了一个 NavigationView 首次加载时 NavigationView 将在其内部启动 然后重新加载后即可正常显示 我不确定是什么原因造成的 我制作了一个 GIF 来更好地说明问题 这
  • Mac 上的 JavaFX WebView 字体问题

    有些网站显示乱码而不是正确的文本 它只发生在 Mac 上 For example with GMapsFX 可能与 OS X 10 11 或 10 12 有关 我用Java 1 8 0 121测试了它 此问题有任何修复或解决方法吗 就我而言
  • 在 SwiftUI 中,如何在 UIView 内部或作为 UIView 使用 UIHostingController?

    另一个问题标题可以是 如何将 UIHostingController 的视图添加为 UIView 的子视图 我正在创建一个新的 UI 组件 并且很乐意尝试 SwiftUI 下图是当前的视图结构 UIView 是我现在正在使用的 右上 Swi
  • 流星 OSX 错误:SQLITE_CANTOPEN:无法打开数据库文件

    我运行了以下命令 meteor create myapp 并收到以下错误消息 错误后重试 Error SQLITE CANTOPEN 无法打开数据库文件 stack Getter 错误后重试 Error SQLITE CANTOPEN 无法
  • 用xCode制作图表[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 您好 我需要绘制一些数组来分析信号 我有一个可可项目正在进行 谁能告诉我在哪里可以找到简化这项任务的工具 基本上我想像在图形计算器上一样显
  • 尝试将存档提交到 App Store 时出现各种 ITMS 错误

    所以这是一个奇怪的问题 当我尝试将我的存档提交到 App Store 时 出现以下错误 ERROR ITMS 90049 This bundle is invalid The bundle identifier contains disal
  • 如何使用核心动画来动画 NSTextField 的背景颜色?

    我正在尝试使用核心动画来突出显示无效的文本字段 my field animator setBackgroundColor NSColor yellowColor 更新字段背景颜色 但不会以动画方式显示更改 正确更新字段位置等属性 我假设这是
  • Amazon EC2 上的 Apple Mac 映像? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我发现要开始苹果应用程序开发 您需要拥有某种 Mac 我想知道是否可以为此目的在 Amazon EC2 实例上加载 Mac OSx 的映像
  • WidgetKit 并发症不会更新

    我们正在迁移ClockKit并发症WidgetKit在我们的手表应用程序中 watchOS 9 迁移很顺利 UI部分工作得很好 然而 我们遇到了小部件在手表应用程序请求时未更新的问题 我相信我们错过了一些非常简单和基本的东西 但到目前为止还

随机推荐

  • 虚拟回调接口

    在 Eclipse 为您创建的来自 Google 的示例主从流代码中 片段中包含以下内容 private Callbacks mCallbacks sDummyCallbacks public interface Callbacks pub
  • 连接数组时合并两个 yaml 文档

    我想合并两个 yaml 文档 结果包含 所有映射值 最后一个优先 串联数组 例如给定这个文件 file1 yml animals elephant donkey flavours sour lemon sweet chocolate str
  • 仅当环境变量具有特定值时如何设置 Apache 标头

    我想在我的 Apache 2 4 配置中设置标头 但前提是环境变量具有特定值 SetEnv ENV NAME prod 我如何仅在以下情况下设置此标头ENV NAME is not prod Header set X Robots Tag
  • 如何使用放心的方式在正文中发送 JsonObject 以进行 post 请求?

    我有一个使用 Google Gson 创建的 JsonObject JsonObject jsonObj gson fromJson response1 json JsonElement class getAsJsonObject 我还对现
  • 设置 IRQ 映射

    我正在遵循一些教程和参考文献来尝试设置我的内核 我在教程中遇到了一些不熟悉的代码 但根本没有解释它 这是我被告知映射的代码16 IRQs 0 15 到 ISR 地点32 47 void irq remap void outportb 0x2
  • 哪里可以找到可靠的 K-medoid(不是 k-means)开源软件/工具? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在学习 K medoids 算法 所以如果我提出不恰当的问题 我很抱歉 据我所知 K medoid
  • 我怎么知道我的所有 goroutine 确实正在使用 golang 的同步包等待一个条件

    我有一个应用程序 我正在创建多个 goroutine 来同时执行某个任务 所有工作协程都会等待条件 事件发生 一旦事件被触发 它们就会开始执行 创建完所有goroutines后 主线程在发送广播信号之前应该知道所有goroutines确实处
  • Paypal 付款标准默认输入卡详细信息

    我确信这个主题已经在这里了 但我刚刚与 Paypal 通电话 试图查明他们的帐户上是否有一个设置 可以让客户看到 输入卡详细信息区域 而不是自动 默认设置 引导您登录 注册您的 PayPal 帐户 Paypal 表示没有一个设置可以在他们这
  • 有很多数据库视图可以吗?

    我很少 每月 每季度 使用 Microsoft SQL Server 2005 数据库视图生成数百份 Crystal Reports 报告 在我不读取这些视图的所有时间里 这些视图是否会浪费 CPU 周期和 RAM 因为我很少从视图中读取数
  • IE 中的 Javascript 第 1 行语法错误 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 有人能找出这个第 1 行语法错误是什么吗 我正在尝试在 IE6 和 IE7 中进行调试 但找不到问题的根源 http ci elfster
  • WF 和分层状态机

    搜索 bing 和 google 我发现了一些关于与 Windows 工作流程相关的状态图的信息 但令人惊讶的是很少 我得出的唯一明确的答案是 是的 它可以处理状态图 这里有一个教程 但我想确定的是 Does it support hier
  • 循环中的knitr模板和子文档

    圣诞节前我之前问过跨多个 knitr 文档的单一样式表 https stackoverflow com questions 20370584 single style sheet across multiple knitr document
  • 使用 R 读取和转换二进制原始数据

    我有一个file https drive google com file d 0BxMpk0nhnJy6SFhxd2xuMzJYYlk edit usp sharing其中包含原始 二进制数据和 ascii 它包含一个时间戳和一个代表速度的
  • 如何使用特定版本的NPM?

    如何切换我正在使用的 npm 版本 现在 npm v 1 1 65 但我需要 1 0 x 我尝试过 但出现错误 npm version 1 0 npm ERR version No package json found 有人知道如何使用不同
  • C 静态代码分析器

    您使用哪种静态代码分析器 如果有 我一直在 Python 中使用 PyLint 我对它非常满意 现在我需要类似的 C 代码 为了正常的日常使用 您需要抑制多少输出 维基百科维护着一个静态代码分析工具列表 http en wikipedia
  • 监听 redux 动作

    我想创建一个可重用的 redux 表模块 它将存储和更新页码 显示的总页数等 我可以在所有页面之间共享这些模块 但是 我需要更新操作来触发刷新数据操作 该操作将根据页面到达不同的端点 因此 可能类似于页面特定的监听 RefreshData
  • 从 plist 文件中解码数据

    我丢失了在 Macbook Air 上用 Textwrangler 编写的文本文件中的一些数据 我在扩展名为 plist 的文件中找到了其中一些 文件是用 xml 编写的 如下所示
  • 将 Django 部署到 AWS;傻瓜静态文件

    我对这个项目的最后一步完全迷失了 到目前为止 我已经能够开发一个 Django 应用程序 它可以在本地主机上按照我想要的方式工作 我已经能够将网站部署到 AWS EC2 但我一定错过了有关提供静态文件的一些基本知识 我什至还没有尝试过媒体文
  • 使用 proguard 混淆文件名

    我正在使用 proguard 和 Android Studio 混淆我的 apk 当我反编译我的apk时 我可以看到很多文件 例如aaa java aab java ETC 但我项目中的所有文件都有原始名称 有没有办法混淆我的项目的文件名
  • SwiftUI 更新主菜单 [已解决] kludgey

    真正的问题 你如何更新mainMenu在 SwiftUI 中 它真的可以工作吗 我在 SwiftUI 中构建了一个基于 MacOS 文档的应用程序 其中包括所有内置的文件菜单命令 即关闭 保存 复制 重命名 等 在保存文档之前 我会验证结构