macos在窗口菜单中添加菜单项



我需要添加一个菜单项的地方,例如XCode的地方的" windows "→"开发人员Documentation"菜单项可用。此菜单项需要一个快捷方式,如果窗口打开则需要一个复选标记。当再次选择菜单项时,该菜单项应关闭窗口。

现在我用。

import SwiftUI
import Foundation
import Combine
@main
struct Navigate_DetailApp: App {
@StateObject var listItemsViewModel : ItemModelView = ItemModelView()
@StateObject var appState = AppState()
@State var isProductWindowOpen = false
let someWindow = NSWindow( contentRect: NSRect(x: 0, y: 0, width: 380, height: 300), styleMask: [.titled, .closable],  backing: .buffered, defer: false)

var body: some Scene {
WindowGroup ("New") {
ContentView(appState: appState)
.frame(minWidth: 800, maxWidth: 900, minHeight: 500, maxHeight: 600)
.environmentObject(listItemsViewModel)
}
WindowGroup("Products") {
ProductsView()
}
Toggle("Products-toggle", isOn: $isProductWindowOpen)
.onChange(of: isProductWindowOpen) { ison in
print("isON")
if ison {
print("open")
someWindow.contentView = NSHostingView(rootView: ProductsView())
someWindow.makeKeyAndOrderFront(nil)
} else {
print("close")
someWindow.close()
}
}                               
.keyboardShortcut("0")
Button("Products-but open") {
//OpenWindows.ProductsView.open()
print("Menu Button Open")
someWindow.contentView = NSHostingView(rootView: ProductsView())
someWindow.makeKeyAndOrderFront(nil)
}
.keyboardShortcut("1")
Button("Products-but close") {
print("Menu Button Close")
someWindow.close()
}
.keyboardShortcut("2")
Button("Products-but open/") {
print("Menu Button OpenClose Toggle")
isProductWindowOpen.toggle()
if isProductWindowOpen == true {
print("open")
someWindow.contentView = NSHostingView(rootView: ProductsView())
someWindow.makeKeyAndOrderFront(nil)
} else {
print("close")
someWindow.close()
}
}
.keyboardShortcut("3")
.... OLD CODE
func openProductsWindow() {
someWindow.contentView = NSHostingView(rootView: ProductsView())
self.someWindow.makeKeyAndOrderFront(nil)
}
func closeProductsWindow() {
.... ?? how to close the window
}
....
struct ProductsView: View {
var body: some View {
Text("Products")
.frame(minWidth: 600, maxWidth: 600, minHeight: 400, maxHeight: 400)
}
}

我需要改变什么来完成菜单项的位置并让它关闭窗口。

编辑 =================

再次感谢你,它澄清了一些问题。不幸的是,它不起作用。确实改变了一些代码,试图让它工作,但同样的效果;也没有发生。在调试器中,它从未出现在操作或打印语句中。

使用添加的按钮和它们的代码,它只工作一次。意思是如果我使用'button open'它打开ProductsView,如果我使用'button Close',它关闭窗口,但然后它不再打开它,然而它在调试器中显示打印语句。我能做些什么来让两者都工作,使用按钮切换和正片叠底(没有复选标记)?

用按钮然后让它切换,它也只工作一次。打开和关闭,但它结束了,没有更多的打开或关闭的窗口。调试器显示:

Menu Button OpenClose Toggle
open
Menu Button OpenClose Toggle
close
Menu Button OpenClose Toggle
open
Menu Button OpenClose Toggle
open
Menu Button OpenClose Toggle
close

=========

Step Forward -新代码可以工作,但是…

我确实把State移到了一个StateObject之类的,这很好,我展示了代码。但是为什么你的代码对你有用而对我没用呢?

@main
struct menuItemInsertWindowApp: App {
@StateObject var productMenuState = MenuState()
var body: some Scene {
WindowGroup {
ContentView()
}
WindowGroup("Products") {
ProductsView()
}
.commands {
CommandGroup(replacing: .windowList) {
ProductMenuItem(productMenuState: productMenuState)
}
}
}
}
struct ContentView: View {
var body: some View {
Text("ContentView")
.frame(minWidth: 600, maxWidth: 600, minHeight: 400, maxHeight: 400)
}
}
struct ProductsView: View {
var body: some View {
Text("Products")
.frame(minWidth: 500, maxWidth: 600, minHeight: 300, maxHeight: 400)
}
}
class MenuState : ObservableObject {
@Published var isProductWindowOpen = false
}
struct ProductMenuItem : View {
let someWindow = NSWindow(contentRect: NSRect(x: 0, y: 0, width: 600, height: 400), styleMask: [.titled, .closable], backing: .buffered, defer: false)
@ObservedObject var productMenuState : MenuState
var body: some View {
Toggle("Products - Toggle That Works", isOn: $productMenuState.isProductWindowOpen)
.onChange(of: productMenuState.isProductWindowOpen) { value in
print( "change isProductWindowOpen" )
if value {
print( "ProductWindow Opens" )
someWindow.contentView = NSHostingView(rootView: ProductsView())
someWindow.makeKeyAndOrderFront(nil)
} else {
print( "ProductWindow Closes" )
someWindow.close()
}
}
}
}

它工作但是,如果你看XCode日志,它显示一些奇怪的双称为行。这是因为macOS错误或XCode编译错误或....这是可解的吗?

change isProductWindowOpen
ProductWindow Opens
change isProductWindowOpen
ProductWindow Opens
change isProductWindowOpen
ProductWindow Closes
change isProductWindowOpen
ProductWindow Closes
change isProductWindowOpen
ProductWindow Closes
onChange(of: Bool) action tried to update multiple times per frame.
onChange(of: Bool) action tried to update multiple times per frame.
change isProductWindowOpen
ProductWindow Opens
change isProductWindowOpen
ProductWindow Opens
onChange(of: Bool) action tried to update multiple times per frame.
onChange(of: Bool) action tried to update multiple times per frame.
onChange(of: Bool) action tried to update multiple times per frame.
change isProductWindowOpen
ProductWindow Closes
change isProductWindowOpen
ProductWindow Closes

随后,当我快速按下快捷键时,也会出现该窗口的重复窗口。

有什么建议吗?

to "…在窗口菜单中添加菜单项,您可以尝试以下方法:

CommandGroup(replacing: .windowList) {
Button("Products") {
print("----> clicked Products")
}
}

EDIT-1:给定您的新代码,您也可以尝试这样做,或者类似的事情(根据您的需要调整):

CommandGroup(replacing: .windowList) {
Toggle("Products", isOn: $isProductWindowOpen)
.onChange(of: isProductWindowOpen) { ison in
if ison {
someWindow.contentView = NSHostingView(rootView: ProductsView())
someWindow.makeKeyAndOrderFront(nil)
} else {
someWindow.close()
}
}
}

EDIT-2:这是对我来说工作良好的测试代码。

import SwiftUI
@main
struct TestApp: App {
let someWindow = NSWindow(contentRect: NSRect(x: 0, y: 0, width: 600, height: 400), styleMask: [.titled, .closable], backing: .buffered, defer: false)

@State var isProductWindowOpen = false

var body: some Scene {
WindowGroup {
ContentView()
}
WindowGroup("Products") {
ProductsView()
}
.commands {
CommandGroup(replacing: .windowList) {
Button("Products open") {
print("Products Button Open")
someWindow.contentView = NSHostingView(rootView: ProductsView())
someWindow.makeKeyAndOrderFront(nil)
} .keyboardShortcut("1")

Button("Products close") {
print("Products Button Close")
someWindow.close()
}.keyboardShortcut("2")

Button("Products toggle") {
print("Products toggle")
isProductWindowOpen.toggle()
if isProductWindowOpen {
print("open")
someWindow.contentView = NSHostingView(rootView: ProductsView())
someWindow.makeKeyAndOrderFront(nil)
} else {
print("close")
someWindow.close()
}
}.keyboardShortcut("3")
}
}

}
}
struct ProductsView: View {
var body: some View {
Text("Products")
.frame(minWidth: 600, maxWidth: 600, minHeight: 400, maxHeight: 400)
}
}
struct ContentView: View {
var body: some View {
Text("ContentView")
.frame(minWidth: 600, maxWidth: 600, minHeight: 400, maxHeight: 400)
}
}

最新更新