启用和禁用 CommandGroup 菜单项

Enabling and Disabling CommandGroup Menu Items

我有一个非常简单的示例 macOS 应用程序和一个自定义菜单命令,只是为了测试我的想法,如下所示。

import SwiftUI

@main
struct MenuMonsterMacApp: App {
    @State var fileOpenEnabled: Bool = true
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .frame(width: 480.0, height: 320.0)
        }.commands {
            CommandGroup(after: .newItem) {
                Button {
                    print("Open file, will you?")
                } label: {
                    Text("Open...")
                }
                .keyboardShortcut("O")
                .disabled(false)
            }
        }
    }
}

我想通过单击 ContentView 中的按钮来启用和禁用此命令。所以我创建了一个 ObservableObject class 来观察文件打开命令的布尔值,如下所示。

import SwiftUI

@main
struct MenuMonsterMacApp: App {
    @ObservedObject var menuObservable = MenuObservable()
    @State var fileOpenEnabled: Bool = true
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .frame(width: 480.0, height: 320.0)
        }.commands {
            CommandGroup(after: .newItem) {
                Button {
                    print("Open file, will you?")
                } label: {
                    Text("Open...")
                }
                .keyboardShortcut("O")
                .disabled(!fileOpenEnabled)
            }
        }.onChange(of: menuObservable.fileOpen) { newValue in
            fileOpenEnabled = newValue
        }
    }
}

class MenuObservable: ObservableObject {
    @Published var fileOpen: Bool = true
}

在我的 ContentView 中,它实际上运行了节目,我有以下内容。

import SwiftUI

struct ContentView: View {
    @StateObject var menuObservable = MenuObservable()
    
    var body: some View {
        VStack {
            Button {
                menuObservable.fileOpen.toggle()
            } label: {
                Text("Click to disable 'File Open'")
            }
        }
    }
}

如果我单击该按钮,相关菜单命令的布尔状态不会改变。这是一种错误的方法吗?如果是,如何从 ContentView 启用和禁用菜单命令?谢谢。

单击 ContentView 中的按钮启用和禁用命令, 尝试以下方法,使用传递 environmentObject 和一个单独的视图 菜单按钮。

import SwiftUI

@main
struct MenuMonsterMacApp: App {
    @StateObject var menuObservable = MenuObservable()

    var body: some Scene {
        WindowGroup {
            ContentView().environmentObject(menuObservable)
                .frame(width: 480.0, height: 320.0)
        }.commands {
            CommandGroup(after: .newItem) {
                OpenCommand().environmentObject(menuObservable)
            }
        }
    }
  
}

struct OpenCommand: View {
    @EnvironmentObject var menuObservable: MenuObservable
    
    var body: some View {
        Button {
            print("Open file, will you?")
        } label: {
            Text("Open...")
        }
        .disabled(!menuObservable.fileOpen)
        .keyboardShortcut("O")
    }
}

class MenuObservable: ObservableObject {
    @Published var fileOpen: Bool = true
}

struct ContentView: View {
    @EnvironmentObject var menuObservable: MenuObservable
    
    var body: some View {
        VStack {
            Button {
                menuObservable.fileOpen.toggle()
            } label: {
                Text("Click to disable 'File Open'")
            }
        }
    }
}