Swiftui:子视图没有收到对 observableobject 的更新

Posted

技术标签:

【中文标题】Swiftui:子视图没有收到对 observableobject 的更新【英文标题】:Swiftui: child view does not receive updates to observableobject 【发布时间】:2020-03-20 20:31:10 【问题描述】:

我有一个模型,举例来说,它是一个标签云和一个项目模型:

struct TagCloud: Identifiable, Hashable
  var id: Int
  let tag: String

  static func tagCloud() -> [TagCloud]
   return [ TagCloud(id: 01, tag:"Green"),
           TagCloud(id: 02, tag:"Blue"),
           TagCloud(id: 03, tag:"Red")]
  


struct TaggedItem: Identifiable, Hashable
  var id: Int
  let tag: String
  let item: String

  static func taggedItems() -> [TaggedItem]
   return [ TaggedItem(id: 01, tag:"Green", item: "Tree"),
           TaggedItem(id: 02, tag:"Blue", item: "Sky"),
           TaggedItem(id: 03, tag:"Red", item: "Apple")...]
  

我有一个类来“包含”当前选定的项目:

class SelectedItems: ObservableObject 

 @Published var currentlySelectedItems:[TaggedItem]  = []

 func changeData(forTag tag: String )
  let currentSelection = TaggedItem. taggedItems()
  let filteredList = cardCollection.filter  $0.tag == tag 
  currentlySelectedItems = filteredList
 

在我的父视图中,我从云中选择了一个标签:

struct ParentView: View 

 let tagCloud = TagCloud.tagCloud()
 @ObservedObject var currentSelection : TaggedItem = TaggedItem()
 @State var navigationTag:Int? = nil

  var body: some View 
   NavigationLink(destination: ChildView(), tag: 1, selection: $tag) 
    EmptyView()
   

   VStack
    ScrollView(.horizontal, content: 
     HStack(spacing: 20)
      ForEach( self.tagCloud, id: \.self)  item in
       VStack
        Button(action: 
         self. currentSelection.changeData(forTag: item.tag )
         self.navigationTag = 1
        )
         Text(item.tag)
        .buttonStyle(PlainButtonStyle())
  ..  

子视图包含 ObservedObject。附带说明一下,我还将它设置为 EnvironmentObject。

struct ChildView: View 

 @ObservedObject var currentItems : SelectedItems = SelectedItems()

 var body: some View 
  VStack
   ScrollView(.horizontal, content: 
    HStack(spacing: 20)
     ForEach( currentItems.currentlySelectedItems, id: \.self)  item in
...

问题:

在父视图中,按钮调用 SelectedItems 以创建与所选标签匹配的项目的过滤列表 调用并设置列表(通过打印验证) 但是,数据永远不会“到达”子视图

我用 init() 尝试了很多东西。我尝试将选定的标签传递给孩子,然后在 init() 本身内进行过滤,但由于需要绑定到一个类而受到阻碍。我在其他地方读到尝试使用第二个模型,该模型将由第一个模型更新以触发视图刷新。

通过父视图选择创建此过滤列表并使列表在子视图中可用的正确方法是什么?

【问题讨论】:

【参考方案1】:

这部分应该重新考虑:

let tagCloud = TagCloud.tagCloud()
@ObservedObject var currentSelection : TaggedItem = TaggedItem()
                                       ^^ is a struct, it cannot be observed !!! 

@ObservedObject 必须只应用于@ObservableObject,就像你对SelectedItems 所做的那样,所以这里可能需要另一个ObservableObject 视图模型包装器围绕TaggedItem

【讨论】:

以上是关于Swiftui:子视图没有收到对 observableobject 的更新的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI:如何更改子视图?

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

SwiftUI 绑定到父视图重新渲染子视图

如何在 SwiftUI 子视图中执行函数?

SwiftUI 发送按钮点击到子视图

SwiftUI 动画如何与子视图隔离?