简体   繁体   English

菜单未更新(SwiftUI 错误?)

[英]Menu not updating (SwiftUI bug?)

I'm using macOS Montery Beta 4 along with Xcode 13 Beta 4, and I think I've discovered a bug in SwiftUI .我正在使用 macOS Montery Beta 4 和 Xcode 13 Beta 4,我想我在SwiftUI发现了一个错误。

When using a CommandGroup along with a button that is enabled/disabled based on a condition, the CommandGroup doesn't update.CommandGroup与基于条件启用/禁用的按钮一起使用时, CommandGroup不会更新。 CommandMenu does however.然而, CommandMenu确实如此。

Reproduction:再生产:

  1. Create a new SwiftUI macOS project创建一个新的 SwiftUI macOS 项目
  2. Paste the following code in the App file:将以下代码粘贴到App文件中:
class Test: ObservableObject {
    @Published var num = 0
}

@main
struct TestApp: App {
    @StateObject private var test = Test()
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(test)
        }
        .commands {
            CommandGroup(after: .newItem) {
                Button(action: {}) {
                    Text("Test menu item")
                }
                .disabled(test.num == 0)
            }
        }
    }
}
  1. Paste the following code in the ContentView file:将以下代码粘贴到ContentView文件中:
struct ContentView: View {
    @EnvironmentObject var test: Test
    
    var body: some View {
        Button(action: {
            test.num += 1
        }) {
            Text(String(test.num) + " ---------")
        }
    }
}
  1. Run the app, and click on the File menu.运行应用程序,然后单击“ File菜单。 You should see that "Test menu item" is disabled as expected.您应该会看到“测试菜单项”已按预期禁用。
  2. Click on the button.单击按钮。 This simply increments a number by 1. However, "Test menu item" is still disabled, even though test.num != 0.这只是将数字增加 1。然而,“测试菜单项”仍然被禁用,即使test.num != 0。

The thing is, replacing the CommandGroup with CommandMenu("Test menu") fixes it.问题是,用CommandMenu("Test menu")替换CommandGroup可以修复它。

All the app does is have a menu item that is disabled if a number is zero.该应用程序所做的只是有一个菜单项,如果数字为零,则该菜单项将被禁用。 Pressing the button makes that number not zero, but the menu item stays disabled.按下按钮使该数字不为零,但菜单项保持禁用状态。

Is anybody able to reproduce this, and is this a bug on my part?有没有人能够重现这个,这是我的一个错误吗?

a minor variation of @George_E answer, is this: @George_E 答案的一个小变化,是这样的:

 CommandGroup(after: .newItem) {
       TestView(test: test)
 }
 
 struct TestView: View {
     @ObservedObject var test: Test
  
     var body: some View {
         Button(action: {}) {
             Text("Test menu item")
         }
         .disabled(test.num == 0)
     }
 }

I wouldn't expect that to be intended behaviour.我不希望这是有意的行为。 However, I have found a workaround to fix this.但是,我找到了解决此问题的解决方法。

It's odd that onChange(of:perform:) isn't run when test.num changes, but we can still detect the publisher.奇怪的是,当test.num更改时onChange(of:perform:)没有运行,但我们仍然可以检测到发布者。 So I split this into a separate view and when the view receives a new value, the button is updated.所以我把它拆分成一个单独的视图,当视图接收到一个新值时,按钮就会更新。

Code:代码:

CommandGroup(after: .newItem) {
    TestView(pub: test.$num)
}
struct TestView: View {
    let pub: Published<Int>.Publisher
    @State private var disabled = true

    var body: some View {
        Button(action: {}) {
            Text("Test menu item")
        }
        .disabled(disabled)
        .onReceive(pub) { new in
            disabled = new == 0
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM