首页 > 解决方案 > SwiftUI @Binding 属性不更新嵌套视图 - Xcode 12

问题描述

我在使用 @Binding 属性更新嵌套的 SwiftUI 视图时遇到问题。我用 ObservableObject 协议声明了一个 DataModel:

class DataModel: ObservableObject {
    
    @Published var subjects: [Subject] = []
    ...
}

我将它添加到我的主应用程序中:

@main
struct LessonToTextApp: App {
    
    @ObservedObject private var data = DataModel()
    
    var body: some Scene {
        WindowGroup {
            NavigationView {
                SubjectsView(subjects: $data.subjects) {
                    data.save()
                }
            }
            .onAppear {
                data.load()
            }
        }
    }
}

我将 Subjects 数组传递给第一个视图

struct SubjectsView: View {
    
    @Binding var subjects: [Subject]

    var body: some View {
        List {
            if subjects.isEmpty {
                Text("subjects.empty")
            } else {
                
                ForEach(subjects) { subject in
                    NavigationLink(destination: DetailView(subject: binding(for: subject), saveAction: saveAction)) {
                        CardView(subject: subject)
                    }
                    .listRowBackground(subject.color)
                    .cornerRadius(10)
             }
        }
}

        private func binding(for subject: Subject) -> Binding<Subject> {
               guard let subIndex = subjects.firstIndex(where: { $0.id == subject.id }) else {
                    fatalError("Can't find subject in array")
               }
               return $subjects[subIndex]
         }

然后我使用上面声明的函数绑定将单个主题传递给第二个视图:


struct DetailView: View {
     
    @Binding var subject: Subject

    var body: some View {
         ForEach(subject.lessons) { lesson in
                NavigationLink(destination: LessonView(lesson: lesson)) {                                    
                    Text(lesson.date, style: .date)
                }
         }
         .onDelete { indexSet in
                self.subject.lessons.remove(atOffsets: indexSet)
          }
     }

在 DetailView 中,当我在 ForEach 中删除一个项目时,该项目仍然出现,视图不会更新。

我在 Xcode 12.3 (12C33) 上使用 SwiftUI 2.0

编辑这是模型:

struct Subject: Identifiable, Codable {
    let id: UUID
    var name: String
    var teacher: String
    var color: Color
    var lessons: [Lesson]
}

struct Lesson: Identifiable, Codable {
    let id: UUID
    let date: Date
    var lenghtInMinutes: Int
    var transcript: String
}

标签: iosxcodeswiftui

解决方案


SubjectsView应该把整个DataModel作为@EnvironmentObject

struct LessonToTextApp: App {

@StateObject private var data = DataModel()

var body: some Scene {
    WindowGroup {
        NavigationView {
            SubjectsView().environmentObject(data) {
                data.save()
            }
            ...

struct SubjectsView: View {

@EnvironmentObject var data = DataModel

var body: some View {
    List {
        if data.subjects.isEmpty {
            Text("subjects.empty")
            ...

而且,struct是不可变的

class Subject: Identifiable, Codable, ObservableObject {
    let id: UUID
    @Published var name: String
    @Published var teacher: String
    @Published var color: Color
    ...
}

struct DetailView: View {
 
    @ObservedObject var subject: Subject

    var body: some View {
    ...

这样你就可以DetailView使用

DetailView(subject: subject)

推荐阅读