如何在 SwiftUI 中激活/停用菜单项
Posted
技术标签:
【中文标题】如何在 SwiftUI 中激活/停用菜单项【英文标题】:How to activate / deactivate menu items in SwiftUI 【发布时间】:2021-01-18 02:30:26 【问题描述】:我正在尝试在 Mac os 的 SwiftUI 应用程序中创建自定义菜单项(SwiftUI 应用程序生命周期)。我不太明白以下行为:
在下面的代码中:
import SwiftUI
@main
struct mysqltoolApp: App
@ObservedObject var mysql = MySQL()
var flags = UtilFlags()
var selectedDB = "mysql"
var body: some Scene
let mainWindow = WindowGroup(Text("title"))
ContentView()
.environmentObject(mysql)
.environmentObject(flags)
.windowStyle(HiddenTitleBarWindowStyle())
.commands
CommandMenu("Tools", content:
Button("Connect...", action: flags.connectDialogVisibilityFlag = true ).disabled(mysql.connected)
Button("Disconnect", action: mysql.closeBase()
mysql.connected = false).disabled(!mysql.connected)
)
CommandGroup(after: .help, addition:
Button("Test button", action: print("Test button pressed"))
.disabled(!mysql.connected)
)
return mainWindow
通过 CommandMenu 添加的按钮的行为符合预期(即根据 'mysql.connected' 的更改值激活和停用。通过 CommandGroup 添加的按钮在启动时根据 'mysql.connected' 的值正确配置,但是忽略 'mysql.connected' 的变化,并没有改变它的状态。我错过了什么?
我重写了上面的部分来强调这个问题。简而言之:
import SwiftUI
@main
struct MenuTestApp: App
@State var active = false
var body: some Scene
WindowGroup
ContentView()
.commands(content:
CommandMenu("Tools", content:
Button("Normally active", action: active = !active).disabled(active)
Button("Normally inactive", action: active = !active).disabled(!active)
)
CommandGroup(after: .newItem, addition:
Button("Normally active", action: active = !active).disabled(active)
Button("Normally inactive", action: active = !active).disabled(!active)
)
)
通过 CommandMenu 添加的按钮行为正确(根据 'active' 的值激活和停用。通过 CommandGroup 添加的按钮忽略 'active' 的值并保持其初始状态。
【问题讨论】:
【参考方案1】:我在 Apple 开发中得到了一个很好的建议。论坛(感谢 OOPer!)。它可能无法解决根本原因(它是 SwiftUI 中的错误吗?),但它提供了一个很好的解决方法。如果我将“行为不端”按钮包装到视图中并添加它,一切都会按预期工作:
import SwiftUI
@main
struct MySQLtoolApp: App
@StateObject var mysql = MySQL()
var flags = UtilFlags()
var selectedDB = "mysql"
var body: some Scene
let mainWindow = WindowGroup(Text("title"))
ContentView()
.environmentObject(mysql)
.environmentObject(flags)
.windowStyle(HiddenTitleBarWindowStyle())
.commands
CommandMenu("Tools", content:
Button("Connect...", action: flags.connectDialogVisibilityFlag = true ).disabled(mysql.connected)
Button("Disconnect", action: mysql.closeBase()
mysql.connected = false).disabled(!mysql.connected)
)
CommandGroup(after: .newItem, addition:
MyButtonsGroup().environmentObject(mysql)
)
return mainWindow
struct MyButtonsGroup: View
@EnvironmentObject var mysql: MySQL
var body: some View
Button("Test button", action: print("Test button pressed"))
.disabled(mysql.connected)
【讨论】:
一个奇怪的错误。我的 CommanGroups 在 AppDelegate 中按预期工作...以上是关于如何在 SwiftUI 中激活/停用菜单项的主要内容,如果未能解决你的问题,请参考以下文章