如何在 SwiftUI 中激活/停用菜单项
How to activate / deactivate menu items in SwiftUI
我正在尝试在 SwiftUI 应用程序中为 mac os(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' 的值并保持其初始状态。
我在 Apple dev 中得到了很好的建议。论坛(感谢 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)
}
}
我正在尝试在 SwiftUI 应用程序中为 mac os(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' 的值并保持其初始状态。
我在 Apple dev 中得到了很好的建议。论坛(感谢 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)
}
}