SwiftUI 将数组的元素作为绑定传递给子视图

Posted

技术标签:

【中文标题】SwiftUI 将数组的元素作为绑定传递给子视图【英文标题】:SwiftUI pass elements of an array as bindings to subview 【发布时间】:2020-06-12 06:22:18 【问题描述】:

我尝试制作我的第一个 ios 应用程序,但遇到以下问题,我不明白如何解决它。我有一个选项卡式 MainPageView,我在其中加载所有数据,然后通过不同的视图传递它。当我在任务视图中添加新项目时,新项目出现在列表中,但是当发生使用上下文菜单将任务标记为已完成之类的事情时,我还想更新任务视图

任务结构:

struct Task: Identifiable, Hashable 
     var name: String = ""
     var status: Bool = false
     var notify: Bool = false

MainPageView - 这里的任务在 Firebase 观察下,所以当数据库发生变化时它应该自动更新

struct MainPageView: View 
     @State private var tasks: [Task] = []
     ...
     var body: Some View
          TabView
             TaskPageView(tasklist: self.$tasks) ...

任务页面视图

struct TaskPageView: View 
     @Binding var tasklist: [Task]
     ...
     var body: some View
          NavigationView
             List
               ForEach(self.tasklist, id:\.self) task in
                   NavigationLink(destination: TaskDetView(task: task))
                        TaskView(name: task.name, done: task.status, notify: task.notify).contextMenu
                           Button(action:  //mark task as done in FirebaseDB ) 
                               Image(systemName: "checkmark.circle").foregroundColor(Color.green)
                               Text("Mark as complete")
                    
                   
               
          

和任务视图

struct TaskView: View 
var name: String
var done: Bool
var notify: Bool

var body: some View 
    ZStack
        HStack
            Text(name)
            Spacer()
            if notify
                Image(systemName: "bell")
            
            Text(done ? "Done" : "Not completed").font(.system(size: 10))
        
    

我想要实现的是当用户单击上下文菜单中的标记为完成按钮以强制更改 TaskPageView 列表中 TaskView 中的文本时。我试图创建另一个类,例如 Tasks,它是 ObservableObject,其中任务列表是 @Published,在 MainPageView 中将任务列表设置为 @ObservedObject 并在 ForEach .indices 中使用并将任务作为 tasklist[idx] 传递,但仍然没有成功。

感谢您的宝贵时间!

【问题讨论】:

绑定在深层视图层次结构中可能工作不稳定,因此我建议使用具有 [Observable/Observed]Object 模式的视图模型。 好的,所以我应该创建一个具有已发布任务对象数组的 ObservableObject Tasks 类,然后在 MainPageView 中将其设置为 ObservedObject x,并在从 db 获取数据时附加到 x.list 中。然后在 TaskPageView 中使用 ObservedObject 作为任务列表。在TaskView(这是我卡住的地方)我应该制作任务EnvironmentObject? 【参考方案1】:

为了将来参考,正如您和 Asperi 在 cmets 中所说,您可以创建一个 ObservableObject /一个 StateObject 任务,将任务数组作为 Published 变量放入其中,在主视图中填充任务并将任务传递给子视图可观察对象(不是 StateObject)。您不需要在子视图中创建任务 environmentObject,即使它也可以这样工作。

【讨论】:

以上是关于SwiftUI 将数组的元素作为绑定传递给子视图的主要内容,如果未能解决你的问题,请参考以下文章

从 SwiftUI 的列表中删除列表元素

从 SwiftUI 的列表中删除列表元素

有没有办法在 SwiftUI 中复制手势或处理它们并将它们传递给子视图?

在 SwiftUI 中的 ForEach 中绑定

使用 Core Data 提供的数据(在 SwiftUI 中)并与另一个视图共享

如何将一个 SwiftUI 视图作为变量传递给另一个视图结构