有没有办法在 SwiftUI 的列表中重新加载项目的内容?

Is there a way to reload the content of an item in a list in SwiftUI?

我有一个列表,其中每个项目的标签都表明列表的该部分是否已解锁。我有另一个视图,其中有一个滑块可以控制用户所在的级别。我将两者放在一个 TabView 中,因此当我更改第二个视图中的值时,第一个视图中的项目不会更新。我可以通过关闭并重新打开应用程序或以任何方式刷新视图来更改第一个视图,但我找不到自动执行此操作的方法。有没有办法在进度值更改时更新列表?我知道如何使用 .onChange 代码,但我不知道如何更新列表。这是代码: 内容视图:

struct ContentView: View{
@AppStorage("Progress") public var progress = 1.0
var body: some View{
    VStack{
        Spacer()
        Text("\(Int(progress))")
        Slider(value: $progress, in: 1...5, step: 1)
        NavigationView{
            List{
                ForEach(Chapters){ chapter in
                    NavigationLink {
                        ChapterItemView(chapter: chapter)
                    } label: {
                        ChapterItemView(chapter: chapter)
                    }
                }
            }
            .navigationBarTitle("Lessons")
            .navigationBarBackButtonHidden(true)
        }
    }
}

章节:

struct Chapter: Hashable, Identifiable, Decodable{
let id: Int
let num: Int}
var Chapters = [Chapter(id: 1, num: 1), Chapter(id: 2, num: 2), Chapter(id: 3, num: 3), Chapter(id: 4, num: 4), Chapter(id: 5, num: 5)]

项目:

struct ChapterItemView: View{
var chapter: Chapter
var body: some View{
    HStack{
        if Int(ContentView().progress) >= chapter.num{
            Text("Chapter \(chapter.num)")
        }else{
            Text("\(Image(systemName: "lock.fill"))Chapter \(chapter.num)").opacity(0.5)
        }
        Spacer()
    }
}

这段代码应该可以重现,如果不能重现请告诉我。

将您的 @AppStorage progress 也放在 ChapterView 中。这将更新视图。

@AppStorage@State 的工作方式类似(并且显然将值保存在 UserDefaults 中)。您可以从任何视图访问该值。如果值发生变化,使用它的视图将被重新绘制。

struct ChapterItemView: View{
    
    @AppStorage("Progress") public var progress = 1.0 // here
    let chapter: Chapter
    
    var body: some View{
        HStack{
            if Int(progress) >= chapter.num{ // and here
                Text("Chapter \(chapter.num)")
            }else{
                Text("\(Image(systemName: "lock.fill"))Chapter \(chapter.num)").opacity(0.5)
            }
            Spacer()
        }
    }
}