1

我有一个EnvironmentObject用来生成列表的

class ActivityViewModel: ObservableObject {
    @Published var Activities = [Activity]()
    
    init() {
        self.Activities = ActivityService.fetchActivities()
    }
}

struct Activity: Codable {
    var Id: UUID
    var Name: String
    var Records: [Record]
    
    init(Name:String) {
        self.Id = UUID.init()
        self.Name = Name
        self.Records = [Record]()
    }
}

当我在视图中使用它时,我可以使用 aForEach来访问Activities数组中的每个值。

我的问题是当我使用 NavigationLink 将其传递Activity给另一个视图时,它不是使用EnvironmentObject

我的“父视图”代码:

ForEach(0..<activities.Activities.count, id: \.self) { activity in
    HStack {
        ActivityListItemView(activity: self.activities.Activities[activity])
    }
}

我的孩子查看代码:

struct ActivityListItemView: View {
    let activity: Activity
    
    var body: some View {
        NavigationLink(destination: ActivityDetail(Activity: activity)) {
            HStack {
                VStack {
                    HStack {
                        Text(activity.Name)
                        Text("\(activity.Records.count) records")
                    }
                }
                
                Text(">")
            }
        }
        .buttonStyle(PlainButtonStyle())
    }
}

如果我随后更新 viewModel,我需要将其复制到子视图中。但我不知道如何让它使用EnvironmentObject, 而不仅仅是我传递给视图的变量。

任何帮助,将不胜感激。

编辑:添加活动类型

4

1 回答 1

1

这种方法类似于 Apple 在本教程中的方法。

https://developer.apple.com/tutorials/swiftui/handling-user-input


确认Identifiable Equatable


   struct Activity: Codable, Identifiable, Equatable {
       var id: UUID
       var name: String
   //    var Records: [Record]
       
       init(Name:String) {
           self.id = UUID()
           self.name = Name
   //        self.Records = [Record]()
       }
   }

迭代activity.activities并传递你的view-modelandactivityActivityListItemView

   ForEach(viewModel.activities) { activity in
     HStack {
         ActivityListItemView(viewModel: viewModel, activity: activity)
     }
 }

ActivityListItemView中,找到其活动的索引

private var activityIndex: Int? {
     viewModel.activities.firstIndex(of: activity)
  }

打开activityIndex并传递$viewModel.activities[index]ActivityDetail

var body: some View {
      if let index = activityIndex {
          NavigationLink(destination: ActivityDetail(activity: $viewModel.activities[index])) {
              ...
          }
          ...
      }
  }

@BindingActivityDetail. _


    struct ActivityDetail: View {
        @Binding var activity: Activity
        
        var body: some View {
            ...
        }
    }

一个完整的工作示例。

class ActivityViewModel: ObservableObject {
    @Published var activities = [Activity]()
    
    init() {
        self.activities = [Activity(Name: "A"), Activity(Name: "B"), Activity(Name: "C"), Activity(Name: "D"), Activity(Name: "E")]
    }
}

struct Activity: Codable, Identifiable, Equatable {
    var id: UUID
    var name: String
//    var Records: [Record]
    
    init(Name:String) {
        self.id = UUID()
        self.name = Name
//        self.Records = [Record]()
    }
}


struct ActivityView: View {
   @ObservedObject  var viewModel = ActivityViewModel()
    var body: some View {
        Button(action: {
            self.viewModel.activities.append(Activity(Name: "\(Date())"))
        }, label: {
            Text("Button")
        })
        ForEach(viewModel.activities) { activity in
            HStack {
                ActivityListItemView(viewModel: viewModel, activity: activity)
            }
        }

    }
}


struct ActivityListItemView: View {
    
    @ObservedObject var viewModel: ActivityViewModel
    
    let activity: Activity
    
    private var activityIndex: Int? {
        viewModel.activities.firstIndex(of: activity)
    }
    
    var body: some View {
        if let index = activityIndex {
            NavigationLink(destination: ActivityDetail(activity: $viewModel.activities[index])) {
                HStack {
                    VStack {
                        HStack {
                            Text(activity.name)
    //                        Text("\(activity.Records.count) records")
                        }
                    }
                    Text(">")
                }
            }
            .buttonStyle(PlainButtonStyle())
        }
    }
}


struct ActivityDetail: View {
    @Binding var activity: Activity
    
    var body: some View {
        Text("\(activity.name)")
    }
}

于 2021-01-10T17:01:42.883 回答