SwiftUI:摆脱 SelectionManagerBox<String> 尝试每帧更新多次

The*_*Jof 6 navigation swift swiftui

我花了几个小时试图摆脱我的应用程序上的错误消息:

\n
List with selection: SelectionManagerBox<String> tried to update multiple times per frame.\n
Run Code Online (Sandbox Code Playgroud)\n

这是一款 macOS 14 应用程序。由于我无法找到解决方案,因此我决定尝试创建一个最小的可重现示例。这是这个例子:

\n
import SwiftUI\n\nstruct ContentView: View {\n    @State var selection: String = ""\n    @State var secondSelection: String = ""\n    \n    var body: some View {\n        NavigationSplitView {\n            List(selection: $selection) {\n                NavigationLink("A", value: "A")\n                NavigationLink("B", value: "B")\n                NavigationLink("C", value: "C")\n            }\n        } content: {\n            List(selection: $secondSelection) {\n                NavigationLink("1", value: "1")\n                NavigationLink("2", value: "2")\n                NavigationLink("3", value: "3")\n            }\n        } detail: {\n            Text("\\(selection) - \\(secondSelection)")\n        }\n    }\n}\n\n#Preview {\n    ContentView()\n}\n
Run Code Online (Sandbox Code Playgroud)\n

由于这个例子真的非常简单,我想我们什么也做不了?\n谢谢!

\n

我在我的应用程序上尝试了所有方法,但问题似乎与 SwiftUI 和 NavigationSplitView\xe2\x80\xa6 有关

\n

小智 0

onAppear当我需要自动选择第一个导航项时,我收到了同样的消息。我还对选定的导航项使用了可选选项。

添加非常短的睡眠时间可以消除该消息(目前的解决方法):

enum NavItem: String, Hashable {
    case home
    case buy
}

struct MyView: View {
    @State private var selectedNavItem: NavItem?

    var body: some View {
        NavigationSplitView() {
            List(selection: $selectedNavItem) {
                NavigationLink(value: NavItem.home) { homeLabel }
                NavigationLink(value: NavItem.buy) { buyLabel }
            }
        } detail: {
            switch selectedNavItem {
                case .some(.home):
                    HomeView()
                case .some(.buy):
                    BuyView()
                case .none:
                    Text("")
            }
        }
        .onAppear {
            Task { @MainActor in
                try await Task.sleep(for: .seconds(0.05))
                selectedNavItem = .home
            }
        }
    }

    private var homeLabel: some View { ... }
    private var buyLabel: some View { ... }
}
Run Code Online (Sandbox Code Playgroud)