SwiftUI - 尽管使用了 @Published 和 @ObservedObject,但视图不会更新
Posted
技术标签:
【中文标题】SwiftUI - 尽管使用了 @Published 和 @ObservedObject,但视图不会更新【英文标题】:SwiftUI - View doesn't update despite using @Published and @ObservedObject 【发布时间】:2020-09-19 15:27:05 【问题描述】:我在使用 SwiftUI 更新应用的主视图时遇到了问题。
所以,我有一个 Dog 结构 (Dog.swift):
struct Dog: Identifiable
var id = UUID()
var name: String
var race: String
var age: Int
var gender: String
var sterile: Bool
var pictureURL: String
var location: String
var dogFriendly: Bool
var catFriendly: Bool
var childFriendly: Bool
var needsGarden: Bool
var isClean: Bool
我的目标是在 AddView.swift 中按下这个按钮:
@ObservedObject var viewModel = AddViewModel()
************** LONG UI CODE *******************
.navigationBarItems(trailing:
Button("Publish")
viewModel.dogs.append(Dog(name: self.name, race: races[selectedRace], age: self.age, gender: genders[selectedGender], sterile: self.isSterile, pictureURL: "", location: "", dogFriendly: self.isDogFriendly, catFriendly: self.isCatFriendly, childFriendly: self.isChildFriendly, needsGarden: self.needsGarden, isClean: self.isClean))
print(viewModel.dogs)
)
将狗添加到 AddViewModel.swift 中的 Dog 数组中:
class AddViewModel: ObservableObject
@Published var dogs: [Dog] = []
然后在 CardView 中显示信息:
struct CardView: View
//MARK: - Properties
@State var dog: Dog
//MARK: - View
var body: some View
******* LONG UI CODE ********
并在我的 HomeView 中显示这些 CardView:
struct HomeView: View
@ObservedObject var viewModel = AddViewModel()
var body: some View
ScrollView
VStack
ForEach(viewModel.dogs) dog in
CardView(dog: dog) // this doesn't work
Text(dog.name) // this doesn't work neither
有人可以帮我解决这个问题并就如何进行操作给我建议吗?
感谢您的慷慨帮助!
【问题讨论】:
【参考方案1】:我认为您想在Dog
中附加Array
或AddView
,并在HomeView
中显示更新后的数据。因此,您只需在每个视图中分别声明AddViewModel
的实例。视图内的两个实例不会互相观察。为了解决这个问题,我更喜欢使用Singleton
模式。这是我的示例代码。
struct ContentView: View
@ObservedObject private var viewModel: AddViewModel = .sharedInstance
@State private var showSheet = false
var body: some View
NavigationView
ScrollView
ForEach(viewModel.dogs) dog in
Text(dog.name)
.frame(height: 25)
.navigationTitle("DogZ")
.navigationBarItems(leading: Button(action:
showSheet.toggle()
, label:
Text("Show")
))
.sheet(isPresented: $showSheet, content:
AddView()
)
struct AddView: View
@ObservedObject private var viewModel: AddViewModel = .sharedInstance
@Environment(\.presentationMode) var presentationMode
var body: some View
NavigationView
Text("Sheet Add View")
.navigationBarItems(trailing: Button(action:
viewModel.dogs.append(Dog(name: "Blacky"))
presentationMode.wrappedValue.dismiss()
, label:
Text("Add")
))
class AddViewModel: ObservableObject
@Published var dogs = [Dog]()
static var sharedInstance = AddViewModel()
struct Dog: Identifiable
var id = UUID()
var name: String
【讨论】:
【参考方案2】:将@State 更改为@Bindig 将修复它。
卡片视图:
struct CardView: View
//MARK: - Properties
@Binding var dog: Dog
//MARK: - View
var body: some View
******* LONG UI CODE ********
【讨论】:
以上是关于SwiftUI - 尽管使用了 @Published 和 @ObservedObject,但视图不会更新的主要内容,如果未能解决你的问题,请参考以下文章
如何在 SwiftUI 中使用 Firestore 创建子集合
macOS 应用程序上的 12000 个条目的 FetchRequest 非常慢,但 iOS 应用程序却没有 - 尽管代码相同(macOS Big Sur / iOS 14 上的 SwiftUI)
Swift之深入解析如何结合Core Data和SwiftUI