收到来自 CloudKit 的更新后,SwiftUI 不会更新子视图,但如果子视图内联,则会更新

问题描述 投票:0回答:1

收到来自 CloudKit 的更新后,这将按预期工作:

@Model
final class File {
    var name: String = "" // <- I edit the name on another device in the simple text editor, the editor code is ommited as it's not significant

    init(name: String) {
        self.name = name
    }
}

struct ContentView: View {
    @Query(sort: \File.name) private var files: [File]

    var body: some View {
        NavigationStack {
            ForEach(files) { file in
                NavigationLink(value: file) {
                    Text(file.name) // <- The text updates successfully after CloudKit sync
                }
            }
        }
    }
}

这是同一个应用程序,但带有提取的子视图:

struct ContentView: View {
    @Query(sort: \File.name) private var files: [File]

    var body: some View {
        NavigationStack {
            FilesView(files: files) // <- Just wrapped the code into a separate view
        }
    }
}

struct FilesView: View {
    var files: [File]

    var body: some View {
        ForEach(files) { file in
            NavigationLink(value: file) {
                FileTileView(file: file) // <- Another extracted view
            }
        }
    }
}

struct FileTileView: View {
    var file: File

    var body: some View {
        Text(file.name) // <- Doesn't get updated when CloudKit received the sync update
    }
}

代码是相同的,只是提取了几个视图。为什么不起作用?

swiftui cloudkit
1个回答
0
投票

我连续调试了 6 个小时来解决这个问题。尝试将数据放入 Bindable viewModel 中是可行的。

struct ContentView: View {
    @Query(sort: \File.name) private var files: [File]

    var body: some View {
        NavigationStack {
            FilesView(files: files)
        }
    }
}

struct FilesView: View {
    var files: [File]

    var body: some View {
        ForEach(files) { file in
            NavigationLink(value: file) {
                FileTileView(viewModel: FileTileViewModel(file: file)) // 👈🏼
            }
        }
    }
}

@Observable
class FileTileViewModel { // 👈🏼
    var file: File
    
    init(file: File) {
        self.file = file
    }
}

struct FileTileView: View {
    
    @Bindable var viewModel: FileTileViewModel // 👈🏼
    
    var body: some View {
        Text(viewModel.file.name)
    }
}

注意:不知何故,它不适用于 NavigationPath 和协调器模式。我还没想明白。

© www.soinside.com 2019 - 2024. All rights reserved.