SwiftUI macOS 命令(菜单栏)和视图

2024-03-13

大家好,我开始学习 SwiftUI 和 macOS 开发。我正在使用 SwiftUI 生命周期。如何从菜单栏的聚焦窗口调用函数。

除了Apple文档之外,我还发现这个参考 https://swiftwithmajid.com/2020/11/24/commands-in-swiftui/并且能够使用命令创建菜单项,但我不知道如何从我的角度调用函数。

例如:

假设这是我的应用程序结构:

import SwiftUI

@main
struct ExampleApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }.commands {
        CommandMenu("First menu") {
            Button("Action!") {
                // How do I call the views action function?
            }
        }
    }
}

这是我的观点:

struct ContentView: View {
    public func action() {
        print("It works")
    }
    var body: some View {
        Text("Example")
    }
}

我刚刚输入了示例代码,如果有任何拼写错误,抱歉,但我希望您能明白。


Because ViewSwiftUI 中的 s 是瞬态的,您无法保存对特定实例的引用ContentView调用它的函数。你什么can不过,要做的是更改传递到内容视图的部分状态。

例如:

@main
struct ExampleApp: App {
    @StateObject var appState = AppState()
    
    var body: some Scene {
        WindowGroup {
            ContentView(appState: appState)
                .frame(maxWidth: .infinity, maxHeight: .infinity)
        }.commands {
            CommandMenu("First menu") {
                Button("Action!") {
                    appState.textToDisplay = "\(Date())"
                }
            }
        }
    }
}

class AppState : ObservableObject {
    @Published var textToDisplay = "(not clicked yet)"
}

struct ContentView: View {
    @ObservedObject var appState : AppState
    
    var body: some View {
        Text(appState.textToDisplay)
    }
}

请注意,.commands修改器继续WindowGroup { }

在这个例子中,AppState is an ObservableObject保存应用程序的某些状态。它已经传递到ContentView使用参数。您还可以通过环境对象传递它(https://www.hackingwithswift.com/quick-start/swiftui/how-to-use-environmentobject-to-share-data- Between-views https://www.hackingwithswift.com/quick-start/swiftui/how-to-use-environmentobject-to-share-data-between-views)

单击菜单项时,它会设置textToDisplay这是一个@Published属性于AppState. ContentView每当 @Published 属性时都会更新AppState得到更新。

这是您将使用的模式的总体思路。如果您有此模式未涵盖的用例,请在评论中告诉我。

根据您的评论进行更新:

import SwiftUI
import Combine

@main
struct ExampleApp: App {
    @StateObject var appState = AppState()
    
    var body: some Scene {
        WindowGroup {
            ContentView(appState: appState)
                .frame(maxWidth: .infinity, maxHeight: .infinity)
        }.commands {
            CommandMenu("First menu") {
                Button("Action!") {
                    appState.textToDisplay = "\(Date())"
                }
                Button("Change background color") {
                    appState.contentBackgroundColor = Color.green
                }
                Button("Toggle view") {
                    appState.viewShown.toggle()
                }
                Button("CustomCopy") {
                    appState.customCopy.send()
                }
            }
        }
    }
}

class AppState : ObservableObject {
    @Published var textToDisplay = "(not clicked yet)"
    @Published var contentBackgroundColor = Color.clear
    @Published var viewShown = true
    
    var customCopy = PassthroughSubject<Void,Never>()
}

class ViewModel : ObservableObject {
    @Published var text = "The text I have here"
    var cancellable : AnyCancellable?

    func connect(withAppState appState: AppState) {
        cancellable = appState.customCopy.sink(receiveValue: { _ in
            print("Do custom copy based on my state: \(self.text) or call a function")
        })
    }
}

struct ContentView: View {
    @ObservedObject var appState : AppState
    @State var text = "The text I have here"
    @StateObject private var viewModel = ViewModel()
    
    var body: some View {
        VStack {
            Text(appState.textToDisplay)
                .background(appState.contentBackgroundColor)
            if appState.viewShown {
                Text("Shown?")
            }
        }
        .onReceive(appState.$textToDisplay) { (newText) in
            print("Got new text: \(newText)")
        }
        .onAppear {
            viewModel.connect(withAppState: appState)
        }
    }
}

在我的更新中,您可以看到我已经解决了背景颜色的问题,显示隐藏视图,甚至收到通知(通过onReceive) 当 @Published 属性之一发生更改时。

您还可以查看我如何使用自定义发布者(customCopy) 将动作传递给ContentView's ViewModel

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

SwiftUI macOS 命令(菜单栏)和视图 的相关文章

随机推荐

  • 随机文件生成器代码?

    有没有人有一个简单的 shell 脚本或 c 程序来生成设定大小的随机文件 linux下有随机内容吗 怎么样 head c SIZE dev random gt file
  • 由于 webpack 错误,构建失败

    我突然从下一个 js 应用程序收到以下错误 有什么办法可以解决这个问题吗 pages app tsx Error BABEL C Projects skribeNew app web pages app tsx You gave us a
  • getRotation 始终返回零

    getRotation无论屏幕朝向哪个方向 始终返回零 我正在运行 2 3 的真实设备上运行它 有什么理由吗 Display display WindowManager context getSystemService Context WI
  • 向 UITableViewController 添加可点击和固定的子视图?

    我想将 ADBannerView 对象静态放置到我的 UITableView 屏幕上 这意味着我希望它始终位于我的工具栏 self navigationController toolbar 上方 即使用户滚动 tableview 时也是如此
  • git:如何在不更改提交 ID 的情况下以非交互方式更改已提交的提交消息?

    有没有命令 脚本这需要commit ID or filename已提交的内容作为输入 并更改提交消息而不更改commit ID 我研究了类似的选项git filter branch git rebase git notes但它们不允许更改单
  • 使用exec函数的php后台进程

    我进行了很多搜索以找到确切的答案 但没有找到任何答案 很多人提到我们应该 在命令结束时不等待响应 例如运行bg php在后台 建议这样做 exec usr bin php bg php 但这对我不起作用 主脚本等待完整执行bg php 我也
  • 使用系统帐户执行 SPWebApplication.Update 会引发 SecurityException

    我正在使用 SPWebConfigModification 类进行一些 web config 修改 当将它们添加到 WebApplication 并对其调用 Update 时 它 会抛出 SecurityException 尽管 我以提升的
  • 如何在 Nginx 中设置双向 SSL 以实现自定义位置?

    我有一个带有一些 API 的 Rails 4 项目 该项目运行于nginx v 1 6 3 and https关于生产 Nginx 配置 upstream app Path to Unicorn SOCK file as defined p
  • ListView 始终显示滚动条

    我的应用程序的某些活动中有 ListView 由于 Android 2 1 或 2 2 滚动条仅在用户滚动列表或在开始时滚动很短的时间才会显示 然后滚动条就会消失 是否有可能以某种方式始终显示它们 例如在 Android 1 5 中 在你的
  • 为什么要在类对象的声明中写一个“类”?

    我通常不会这样写 但我见过一个代码库 它几乎无处不在 例如 class prettyClass just class stuff int main class prettyClass obj class return 0 在 C 中 结构的
  • 如何在Android Studio中使用Gradle生成JavaDoc?

    我找不到任何有关如何配置 Gradle 文件来为我的项目创建 JavaDoc 的文档 我已经尝试过 SO 和博客文章中的一些片段 但它们似乎都不起作用 或者它们不提供上下文 这是我的 Gradle 文件 我需要做什么来添加生成 JavaDo
  • 如何使用“npm login”设置 npm 凭据而不从 stdin 读取?

    我正在尝试自动化npm publish在 Docker 容器内 但是当npm login命令尝试读取用户名和电子邮件 npm login lt lt EOF username password email EOF 它可以在 Bash 终端中
  • 服务器套接字 - 仅接受来自白名单中的 IP 地址的连接

    我有一个套接字服务器 它侦听并接受来自客户端的连接 其工作原理如下 do some pre processing socket binds etc listen to client if listen sockfd BACKLOG 1 pe
  • 将列表列表解压到列表中[重复]

    这个问题在这里已经有答案了 我有元组列表的列表 a 1 2 3 4 5 6 7 8 9 10 我怎样才能制作一个元组列表 b 1 2 3 4 5 6 7 8 9 10 天真的方法是 b for c in a for t in c b app
  • 贝塞尔曲线与线段的交点

    我正在用 Python 使用 pygame 编写一个游戏 它要求我为每个新游戏生成随机但美观的 海洋 经过长时间的搜索 我确定了一种涉及贝塞尔曲线的算法 如padlib py http www pygame org project Pyga
  • TypeScript 抱怨 array.map 不存在于 string[] 类型的数组上

    我有一个使用 TypeScript 的 Angular 2 项目 我不明白为什么 TypeScript 实时编译器会抱怨info map 错误消息 未解析的函数或方法 map 当我在浏览器中运行它时 工作得很好 但我不明白为什么会发生这种情
  • VBScript 函数的返回值

    我有两个函数 我试图在第二个函数中使用一个函数的结果 它将前往else部分 但它没有打印 cus number 的任何内容 如何打印 cus number Function getNumber number 423 End Function
  • Laravel 高级搜索查询修复

    我有一个带有多个输入和选择框的搜索表单 我需要帮助来获取查询中的 if 条件 以便每个部分同时单独工作 这是我的刀片代码
  • pymodbus TcpClient超时

    我遇到 pymodbus TcpClient 超时问题 import logging from pymodbus client sync import ModbusTcpClient logging basicConfig log logg
  • SwiftUI macOS 命令(菜单栏)和视图

    大家好 我开始学习 SwiftUI 和 macOS 开发 我正在使用 SwiftUI 生命周期 如何从菜单栏的聚焦窗口调用函数 除了Apple文档之外 我还发现这个参考 https swiftwithmajid com 2020 11 24