在 SwiftUI 中,如何限制 ObservableObject 的哪些 @Published 属性触发视图刷新?

ken*_*nyc 5 swift swiftui

在 中SwiftUI,有没有办法控制触发视图@Published中的哪些属性@ObservableObject要刷新?

\n

model在 iPad 和 macOS 上,我发现在屏幕上同时呈现的多个视图之间共享是很常见的。这model是一个ObservableObject具有众多属性的@Published. 然而,任何这些属性的出现似乎都会导致 SwiftUI 重建视图层次结构,即使并非完全必要。

\n

考虑下面的例子。有一个model调用Order具有多个已发布的属性。有两种并列提出的观点都依赖于Order。如果您对 进行更改Order.nameOrder.address从 进行更改CustomerView,那么也会触发CartView进行刷新,即使它仅依赖于Order.items

\n

理想情况下,我想要一种方法来告诉忽略CustomerView对和 的更新。但由于是一个我不知道该怎么做。Order.itemsCartViewOrder.nameOrder.addressorder@EnvironmentObject

\n

替代解决方案:

\n

我可以解决这个问题的一种方法是不使用@EnvironmentObject而只是Order通过标准属性初始值设定项传递。然后声明单独的@Binding属性CustomerViewCartView来管理状态。这是可行的,但如果视图和模型有很多属性,很快就会变得大量重复。

\n

并不是太重要,但这主要是针对 iPadOS 和 macOS 开发。

\n
\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n\xe2\x94\x82               ContentView                \xe2\x94\x82\n\xe2\x94\x82                                          \xe2\x94\x82\n\xe2\x94\x82\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90 \xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90 \xe2\x94\x82\n\xe2\x94\x82\xe2\x94\x82                  \xe2\x94\x82 \xe2\x94\x82                  \xe2\x94\x82 \xe2\x94\x82\n\xe2\x94\x82\xe2\x94\x82   CustomerView   \xe2\x94\x82 \xe2\x94\x82      CartView    \xe2\x94\x82 \xe2\x94\x82\n\xe2\x94\x82\xe2\x94\x82                  \xe2\x94\x82 \xe2\x94\x82                  \xe2\x94\x82 \xe2\x94\x82\n\xe2\x94\x82\xe2\x94\x82                  \xe2\x94\x82 \xe2\x94\x82                  \xe2\x94\x82 \xe2\x94\x82\n\xe2\x94\x82\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98 \xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n\n\n\nfinal class Order: ObservableObject {\n  @Published var name: String\n  @Published var items: [Item]\n  @Published var address: String\n}\n\nstruct ContentView: View {\n  @StateObject var order = Order()\n  \n  var body: some View {\n    HStack {\n      CustomerView()\n      CartView()\n    }.environmentObject(order)\n  }\n}\n\nstruct CustomerView: View {\n  @EnvironmentObject var order: Order\n  \n  // This view gets rebuilt when 'order.items' is changed.\n  var body: some View {\n    VStack {\n      TextField("Name", text: $order.name)\n      TextField("Address", text: $order.address)\n    }\n  }\n}\n\nstruct CartView: View {\n  @EnvironmentObject var order: Order\n  \n  // This view gets rebuilt when 'order.name' or 'order.address' is changed.\n  var body: some View {\n    List(order.items, id: \\.id) { item in\n      ItemView(item)\n    }\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n